Skip to content

Commit 6d681f0

Browse files
committed
Merge branch 'jl/status-added-submodule-is-never-ignored'
submodule.*.ignore and diff.ignoresubmodules are used to ignore all submodule changes in "diff" output, but it can be confusing to apply these configuration values to status and commit. This is a backward-incompatible change, but should be so in a good way (aka bugfix). * jl/status-added-submodule-is-never-ignored: commit -m: commit staged submodules regardless of ignore config status/commit: show staged submodules regardless of ignore config
2 parents 83a4904 + c215d3d commit 6d681f0

File tree

5 files changed

+108
-8
lines changed

5 files changed

+108
-8
lines changed

Documentation/config.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,7 +2301,9 @@ status.submodulesummary::
23012301
--summary-limit option of linkgit:git-submodule[1]). Please note
23022302
that the summary output command will be suppressed for all
23032303
submodules when `diff.ignoreSubmodules` is set to 'all' or only
2304-
for those submodules where `submodule.<name>.ignore=all`. To
2304+
for those submodules where `submodule.<name>.ignore=all`. The only
2305+
exception to that rule is that status and commit will show staged
2306+
submodule changes. To
23052307
also view the summary for ignored submodules you can either use
23062308
the --ignore-submodules=dirty command-line option or the 'git
23072309
submodule summary' command, which shows a similar output but does
@@ -2332,7 +2334,9 @@ submodule.<name>.fetchRecurseSubmodules::
23322334
submodule.<name>.ignore::
23332335
Defines under what circumstances "git status" and the diff family show
23342336
a submodule as modified. When set to "all", it will never be considered
2335-
modified, "dirty" will ignore all changes to the submodules work tree and
2337+
modified (but it will nonetheless show up in the output of status and
2338+
commit when it has been staged), "dirty" will ignore all changes
2339+
to the submodules work tree and
23362340
takes only differences between the HEAD of the submodule and the commit
23372341
recorded in the superproject into account. "untracked" will additionally
23382342
let submodules with modified tracked files in their work tree show up.

Documentation/gitmodules.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ submodule.<name>.fetchRecurseSubmodules::
6767
submodule.<name>.ignore::
6868
Defines under what circumstances "git status" and the diff family show
6969
a submodule as modified. When set to "all", it will never be considered
70-
modified, "dirty" will ignore all changes to the submodules work tree and
70+
modified (but will nonetheless show up in the output of status and
71+
commit when it has been staged), "dirty" will ignore all changes
72+
to the submodules work tree and
7173
takes only differences between the HEAD of the submodule and the commit
7274
recorded in the superproject into account. "untracked" will additionally
7375
let submodules with modified tracked files in their work tree show up.

builtin/commit.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,8 +898,22 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
898898

899899
if (get_sha1(parent, sha1))
900900
commitable = !!active_nr;
901-
else
902-
commitable = index_differs_from(parent, 0);
901+
else {
902+
/*
903+
* Unless the user did explicitly request a submodule
904+
* ignore mode by passing a command line option we do
905+
* not ignore any changed submodule SHA-1s when
906+
* comparing index and parent, no matter what is
907+
* configured. Otherwise we won't commit any
908+
* submodules which were manually staged, which would
909+
* be really confusing.
910+
*/
911+
int diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
912+
if (ignore_submodule_arg &&
913+
!strcmp(ignore_submodule_arg, "all"))
914+
diff_flags |= DIFF_OPT_IGNORE_SUBMODULES;
915+
commitable = index_differs_from(parent, diff_flags);
916+
}
903917
}
904918
strbuf_release(&committer_ident);
905919

t/t7508-status.sh

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,15 +1379,40 @@ EOF
13791379
test_i18ncmp expect output
13801380
'
13811381

1382-
test_expect_success '.gitmodules ignore=all suppresses submodule summary' '
1382+
test_expect_success '.gitmodules ignore=all suppresses unstaged submodule summary' '
1383+
cat > expect << EOF &&
1384+
On branch master
1385+
Changes to be committed:
1386+
(use "git reset HEAD <file>..." to unstage)
1387+
1388+
modified: sm
1389+
1390+
Changes not staged for commit:
1391+
(use "git add <file>..." to update what will be committed)
1392+
(use "git checkout -- <file>..." to discard changes in working directory)
1393+
1394+
modified: dir1/modified
1395+
1396+
Untracked files:
1397+
(use "git add <file>..." to include in what will be committed)
1398+
1399+
.gitmodules
1400+
dir1/untracked
1401+
dir2/modified
1402+
dir2/untracked
1403+
expect
1404+
output
1405+
untracked
1406+
1407+
EOF
13831408
git config --add -f .gitmodules submodule.subname.ignore all &&
13841409
git config --add -f .gitmodules submodule.subname.path sm &&
13851410
git status > output &&
13861411
test_cmp expect output &&
13871412
git config -f .gitmodules --remove-section submodule.subname
13881413
'
13891414

1390-
test_expect_success '.git/config ignore=all suppresses submodule summary' '
1415+
test_expect_success '.git/config ignore=all suppresses unstaged submodule summary' '
13911416
git config --add -f .gitmodules submodule.subname.ignore none &&
13921417
git config --add -f .gitmodules submodule.subname.path sm &&
13931418
git config --add submodule.subname.ignore all &&
@@ -1460,4 +1485,49 @@ test_expect_success 'Restore default test environment' '
14601485
git config --unset status.showUntrackedFiles
14611486
'
14621487

1488+
test_expect_success 'git commit will commit a staged but ignored submodule' '
1489+
git config --add -f .gitmodules submodule.subname.ignore all &&
1490+
git config --add -f .gitmodules submodule.subname.path sm &&
1491+
git config --add submodule.subname.ignore all &&
1492+
git status -s --ignore-submodules=dirty >output &&
1493+
test_i18ngrep "^M. sm" output &&
1494+
GIT_EDITOR="echo hello >>\"\$1\"" &&
1495+
export GIT_EDITOR &&
1496+
git commit -uno &&
1497+
git status -s --ignore-submodules=dirty >output &&
1498+
test_i18ngrep ! "^M. sm" output
1499+
'
1500+
1501+
test_expect_success 'git commit --dry-run will show a staged but ignored submodule' '
1502+
git reset HEAD^ &&
1503+
git add sm &&
1504+
cat >expect << EOF &&
1505+
On branch master
1506+
Changes to be committed:
1507+
(use "git reset HEAD <file>..." to unstage)
1508+
1509+
modified: sm
1510+
1511+
Changes not staged for commit:
1512+
(use "git add <file>..." to update what will be committed)
1513+
(use "git checkout -- <file>..." to discard changes in working directory)
1514+
1515+
modified: dir1/modified
1516+
1517+
Untracked files not listed (use -u option to show untracked files)
1518+
EOF
1519+
git commit -uno --dry-run >output &&
1520+
test_i18ncmp expect output &&
1521+
git status -s --ignore-submodules=dirty >output &&
1522+
test_i18ngrep "^M. sm" output
1523+
'
1524+
1525+
test_expect_success 'git commit -m will commit a staged but ignored submodule' '
1526+
git commit -uno -m message &&
1527+
git status -s --ignore-submodules=dirty >output &&
1528+
test_i18ngrep ! "^M. sm" output &&
1529+
git config --remove-section submodule.subname &&
1530+
git config -f .gitmodules --remove-section submodule.subname
1531+
'
1532+
14631533
test_done

wt-status.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,19 @@ static void wt_status_collect_changes_index(struct wt_status *s)
519519
opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
520520
setup_revisions(0, NULL, &rev, &opt);
521521

522+
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
522523
if (s->ignore_submodule_arg) {
523-
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
524524
handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
525+
} else {
526+
/*
527+
* Unless the user did explicitly request a submodule ignore
528+
* mode by passing a command line option we do not ignore any
529+
* changed submodule SHA-1s when comparing index and HEAD, no
530+
* matter what is configured. Otherwise the user won't be
531+
* shown any submodules she manually added (and which are
532+
* staged to be committed), which would be really confusing.
533+
*/
534+
handle_ignore_submodules_arg(&rev.diffopt, "dirty");
525535
}
526536

527537
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;

0 commit comments

Comments
 (0)