diff-lib: honor override_submodule_config flag bit

When `diff.ignoreSubmodules = all` is set and submodule commits are manually staged (e.g. via `git-update-index`), `git-commit` should record the commit with updated submodules. `index_differs_from` is called from `prepare_to_commit` with flags set to `override_submodule_config = 1`. `index_differs_from` then merges the default diff flags and passed flags. When `diff.ignoreSubmodules` is set to "all", `flags` ends up having both `override_submodule_config` and `ignore_submodules` set to 1. This results in `git-commit` ignoring staged commits. This patch restores original `flags.ignore_submodule` if `flags.override_submodule_config` is set. Signed-off-by: Josip Sokcevic <sokcevic@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Josip Sokcevic committed Jun 14, 2023 at 09:48 UTC 5768478edc2bccb6a3d6200e430490573140bfa6
2 files changed +31 -1
diff-lib.c
+8 -1
@@ -669,8 +669,15 @@ int index_differs_from(struct repository *r,
669 setup_revisions(0, NULL, &rev, &opt);
670 rev.diffopt.flags.quick = 1;
671 rev.diffopt.flags.exit_with_status = 1;
672 - if (flags)
672 + if (flags) {
673 diff_flags_or(&rev.diffopt.flags, flags);
674 + /*
675 + * Now that flags are merged, honor override_submodule_config
676 + * and ignore_submodules from passed flags.
677 + */
678 + if (flags->override_submodule_config)
679 + rev.diffopt.flags.ignore_submodules = flags->ignore_submodules;
680 + }
681 rev.diffopt.ita_invisible_in_index = ita_invisible_in_index;
682 run_diff_index(&rev, 1);
683 has_changes = rev.diffopt.flags.has_changes;
t/t7406-submodule-update.sh
+23
@@ -1179,4 +1179,27 @@ test_expect_success 'submodule update --recursive skip submodules with strategy=
1179 test_cmp expect.err actual.err
1180 '
1181
1182 +add_submodule_commit_and_validate () {
1183 + HASH=$(git rev-parse HEAD) &&
1184 + git update-index --add --cacheinfo 160000,$HASH,sub &&
1185 + git commit -m "create submodule" &&
1186 + echo "160000 commit $HASH sub" >expect &&
1187 + git ls-tree HEAD -- sub >actual &&
1188 + test_cmp expect actual
1189 +}
1190 +
1191 +test_expect_success 'commit with staged submodule change' '
1192 + add_submodule_commit_and_validate
1193 +'
1194 +
1195 +test_expect_success 'commit with staged submodule change with ignoreSubmodules dirty' '
1196 + test_config diff.ignoreSubmodules dirty &&
1197 + add_submodule_commit_and_validate
1198 +'
1199 +
1200 +test_expect_success 'commit with staged submodule change with ignoreSubmodules all' '
1201 + test_config diff.ignoreSubmodules all &&
1202 + add_submodule_commit_and_validate
1203 +'
1204 +
1205 test_done