]> git.ipfire.org Git - thirdparty/git.git/commitdiff
add -p: ignore dirty submodules
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Thu, 1 Sep 2022 15:42:19 +0000 (15:42 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 1 Sep 2022 16:55:28 +0000 (09:55 -0700)
Thanks to always running `diff-index` and `diff-files` with the
`--numstat` option (the latter with `--ignore-submodules=dirty`) before
even generating any real diff to parse, the Perl version of `git add -p`
simply ignored dirty submodules and does not even offer them up for
staging.

However, the built-in variant did not use that flag because it tries to
run only one `diff` command, skipping the unneeded
`diff-index`/`diff-files` invocation of the Perl variant and therefore
only faithfully recapitulates what the Perl code does once it _does_
generate and parse the real diff.

This causes a problem when running the built-in `add -p` with
`diff-so-fancy` because that diff colorizer always inserts an empty line
before the diff header to ensure that it produces 4 lines as expected by
`git add -p` (the equivalent of the non-colorized `diff`, `index`, `---`
and `+++` lines). But `git diff-files` does not produce any `index` line
for dirty submodules.

The underlying problem is not even the discrepancy in lines, but that
`git add -p` presents diffs for dirty submodules: there is nothing that
_can_ be staged for those.

Let's fix that bug, and teach the built-in `add -p` to ignore dirty
submodules, too. This _incidentally_ also fixes the `diff-so-fancy`
problem ;-)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
add-patch.c
t/t3701-add-interactive.sh

index a6bd150de5112bfbbc318f51ee280e4f67be2c85..a65965328671442ba805e55f3805976b9298d14e 100644 (file)
@@ -419,7 +419,8 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
        }
        color_arg_index = args.nr;
        /* Use `--no-color` explicitly, just in case `diff.color = always`. */
-       strvec_pushl(&args, "--no-color", "-p", "--", NULL);
+       strvec_pushl(&args, "--no-color", "--ignore-submodules=dirty", "-p",
+                    "--", NULL);
        for (i = 0; i < ps->nr; i++)
                strvec_push(&args, ps->items[i].original);
 
index 447fc3380afabb70722be003a0dfc9883724e903..b6b309414ee99132d49d3a8b5dfb2059171eba87 100755 (executable)
@@ -942,6 +942,18 @@ test_expect_success 'status ignores dirty submodules (except HEAD)' '
        ! grep dirty-otherwise output
 '
 
+test_expect_success 'handle submodules' '
+       echo 123 >>for-submodules/dirty-otherwise/initial.t &&
+
+       force_color git -C for-submodules add -p dirty-otherwise >output 2>&1 &&
+       grep "No changes" output &&
+
+       force_color git -C for-submodules add -p dirty-head >output 2>&1 <y &&
+       git -C for-submodules ls-files --stage dirty-head >actual &&
+       rev="$(git -C for-submodules/dirty-head rev-parse HEAD)" &&
+       grep "$rev" actual
+'
+
 test_expect_success 'set up pathological context' '
        git reset --hard &&
        test_write_lines a a a a a a a a a a a >a &&