Skip to content

Commit 1d2f393

Browse files
jlehmanngitster
authored andcommitted
status/commit: show staged submodules regardless of ignore config
Currently setting submodule.<name>.ignore and/or diff.ignoreSubmodules to "all" suppresses all output of submodule changes for the diff family, status and commit. For status and commit this is really confusing, as it even when the user chooses to record a new commit for an ignored submodule by adding it manually this change won't show up under the to-be-committed changes. To add insult to injury, a later "git commit" will error out with "nothing to commit" when only ignored submodules are staged. Fix that by making wt_status always print staged submodule changes, no matter what ignore settings are configured. The only exception is when the user explicitly uses the "--ignore-submodules=all" command line option, in that case the submodule output is still suppressed. This also makes "git commit" work again when only modifications of ignored submodules are staged, as that command uses the "commitable" member of the wt_status struct to determine if staged changes are present. But this only happens when the commit command uses the wt_status* functions to produce status output for human consumption (when forking an editor or with --dry-run), in all other cases (e.g. when run in a script with '-m') another code path is taken which uses index_differs_from() to determine if any changes are staged which still ignores submodules according to their configuration. This will be fixed in a follow-up commit. Change t7508 to reflect this new behavior and add three new tests to show that a single staged submodule configured to be ignored will be committed when the status output is generated and won't be if not. Also update the documentation of the ignore config options accordingly. Signed-off-by: Jens Lehmann <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5f95c9f commit 1d2f393

File tree

4 files changed

+92
-6
lines changed

4 files changed

+92
-6
lines changed

Documentation/config.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,7 +2227,9 @@ status.submodulesummary::
22272227
--summary-limit option of linkgit:git-submodule[1]). Please note
22282228
that the summary output command will be suppressed for all
22292229
submodules when `diff.ignoreSubmodules` is set to 'all' or only
2230-
for those submodules where `submodule.<name>.ignore=all`. To
2230+
for those submodules where `submodule.<name>.ignore=all`. The only
2231+
exception to that rule is that status and commit will show staged
2232+
submodule changes. To
22312233
also view the summary for ignored submodules you can either use
22322234
the --ignore-submodules=dirty command line option or the 'git
22332235
submodule summary' command, which shows a similar output but does
@@ -2258,7 +2260,9 @@ submodule.<name>.fetchRecurseSubmodules::
22582260
submodule.<name>.ignore::
22592261
Defines under what circumstances "git status" and the diff family show
22602262
a submodule as modified. When set to "all", it will never be considered
2261-
modified, "dirty" will ignore all changes to the submodules work tree and
2263+
modified (but it will nonetheless show up in the output of status and
2264+
commit when it has been staged), "dirty" will ignore all changes
2265+
to the submodules work tree and
22622266
takes only differences between the HEAD of the submodule and the commit
22632267
recorded in the superproject into account. "untracked" will additionally
22642268
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.

t/t7508-status.sh

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

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

1391-
test_expect_success '.git/config ignore=all suppresses submodule summary' '
1416+
test_expect_success '.git/config ignore=all suppresses unstaged submodule summary' '
13921417
git config --add -f .gitmodules submodule.subname.ignore none &&
13931418
git config --add -f .gitmodules submodule.subname.path sm &&
13941419
git config --add submodule.subname.ignore all &&
@@ -1461,4 +1486,49 @@ test_expect_success 'Restore default test environment' '
14611486
git config --unset status.showUntrackedFiles
14621487
'
14631488

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

wt-status.c

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

489+
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
489490
if (s->ignore_submodule_arg) {
490-
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
491491
handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
492+
} else {
493+
/*
494+
* Unless the user did explicitly request a submodule ignore
495+
* mode by passing a command line option we do not ignore any
496+
* changed submodule SHA-1s when comparing index and HEAD, no
497+
* matter what is configured. Otherwise the user won't be
498+
* shown any submodules she manually added (and which are
499+
* staged to be committed), which would be really confusing.
500+
*/
501+
handle_ignore_submodules_arg(&rev.diffopt, "dirty");
492502
}
493503

494504
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;

0 commit comments

Comments
 (0)