Skip to content

Commit 287a870

Browse files
committed
Merge branch 'jl/status-added-submodule-is-never-ignored' into maint
"git status" (and "git commit") behaved as if changes in a modified submodule are not there if submodule.*.ignore configuration is set, which was misleading. The configuration is only to unclutter diff output during the course of development, and should not to hide changes in the "status" output to cause the users forget to commit them. * 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 1881d2b + c215d3d commit 287a870

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
@@ -2293,7 +2293,9 @@ status.submodulesummary::
22932293
--summary-limit option of linkgit:git-submodule[1]). Please note
22942294
that the summary output command will be suppressed for all
22952295
submodules when `diff.ignoreSubmodules` is set to 'all' or only
2296-
for those submodules where `submodule.<name>.ignore=all`. To
2296+
for those submodules where `submodule.<name>.ignore=all`. The only
2297+
exception to that rule is that status and commit will show staged
2298+
submodule changes. To
22972299
also view the summary for ignored submodules you can either use
22982300
the --ignore-submodules=dirty command line option or the 'git
22992301
submodule summary' command, which shows a similar output but does
@@ -2324,7 +2326,9 @@ submodule.<name>.fetchRecurseSubmodules::
23242326
submodule.<name>.ignore::
23252327
Defines under what circumstances "git status" and the diff family show
23262328
a submodule as modified. When set to "all", it will never be considered
2327-
modified, "dirty" will ignore all changes to the submodules work tree and
2329+
modified (but it will nonetheless show up in the output of status and
2330+
commit when it has been staged), "dirty" will ignore all changes
2331+
to the submodules work tree and
23282332
takes only differences between the HEAD of the submodule and the commit
23292333
recorded in the superproject into account. "untracked" will additionally
23302334
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
@@ -832,8 +832,22 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
832832

833833
if (get_sha1(parent, sha1))
834834
commitable = !!active_nr;
835-
else
836-
commitable = index_differs_from(parent, 0);
835+
else {
836+
/*
837+
* Unless the user did explicitly request a submodule
838+
* ignore mode by passing a command line option we do
839+
* not ignore any changed submodule SHA-1s when
840+
* comparing index and parent, no matter what is
841+
* configured. Otherwise we won't commit any
842+
* submodules which were manually staged, which would
843+
* be really confusing.
844+
*/
845+
int diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
846+
if (ignore_submodule_arg &&
847+
!strcmp(ignore_submodule_arg, "all"))
848+
diff_flags |= DIFF_OPT_IGNORE_SUBMODULES;
849+
commitable = index_differs_from(parent, diff_flags);
850+
}
837851
}
838852
strbuf_release(&committer_ident);
839853

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_success '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
@@ -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)