From dc6264157236fb729ad072e18f14d89549c08555 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Sep 2020 04:08:53 -0400 Subject: add-patch: fix inverted return code of repo_read_index() After applying hunks to a file with "add -p", the C patch_update_file() function tries to refresh the index (just like the perl version does). We can only refresh the index if we're able to read it in, so we first check the return value of repo_read_index(). But unlike many functions, where "0" is success, that function is documented to return the number of entries in the index. Hence we should be checking for success with a non-negative return value. Neither the tests nor any users seem to have noticed this, probably due to a combination of: - this affects only the C version, which is not yet the default - following it up with any porcelain command like "git diff" or "git commit" would refresh the index automatically. But you can see the problem by running the plumbing "git diff-files" immediately after "add -p" stages all hunks. Running the new test with GIT_TEST_ADD_I_USE_BUILTIN=1 fails without the matching code change. Signed-off-by: Jeff King Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- add-patch.c | 2 +- t/t3701-add-interactive.sh | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/add-patch.c b/add-patch.c index f899389e2c..e6fa10715d 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1624,7 +1624,7 @@ soft_increment: NULL, 0, NULL, 0)) error(_("'git apply' failed")); } - if (!repo_read_index(s->s.r)) + if (repo_read_index(s->s.r) >= 0) repo_refresh_and_write_index(s->s.r, REFRESH_QUIET, 0, 1, NULL, NULL, NULL); } diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 49decbac71..f0a491ade1 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -560,6 +560,13 @@ test_expect_success 'patch mode ignores unmerged entries' ' diff_cmp expected diff ' +test_expect_success 'index is refreshed after applying patch' ' + git reset --hard && + echo content >test && + printf y | git add -p && + git diff-files --exit-code +' + test_expect_success 'diffs can be colorized' ' git reset --hard && -- cgit v1.2.3 From 1c6ffb546bf5d31c2cef2fefc86317658fda59e0 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Sep 2020 04:17:39 -0400 Subject: add--interactive.perl: specify --no-color explicitly Our color tests of "git add -p" do something a bit different from how a normal user would behave: we pretend there's a pager in use, so that Git thinks it's OK to write color to a non-tty stdout. This comes from 8539b46534 (t3701: avoid depending on the TTY prerequisite, 2019-12-06), which allows us to avoid a lot of complicated mock-tty code. However, those environment variables also make their way down to sub-processes of add--interactive, including the "diff-files" we run to generate the patches. As a result, it thinks it should output color, too. So in t3701.50, for example, the machine-readable version of the diff we get unexpectedly has color in it. We fail to parse it as a diff and think there are zero hunks. The test does still pass, though, because even with zero hunks we'll dump the diff header (and we consider those unparseable bits to be part of the header!), and so the output still has the expected color codes in it. We don't notice that the command was totally broken and failed to apply anything. And in fact we're not really testing what we think we are about the color, either. While add--interactive does correctly show the version we got from running "diff-files --color", we'd also pass the test if we had accidentally shown the machine-readable version, too, since it (erroneously) has color codes in it. One could argue that the test isn't very realistic; it's setting up this "pretend there's a pager" situation to get around the tty restrictions of the test environment. So one option would be to move back towards using a real tty. But the behavior of add--interactive really is user-visible here. If a user, for whatever reason, did run "git --paginate add --patch" (perhaps because their pager is really a filter or something), the command would totally fail to do anything useful. Since we know that we don't want color in this output, let's just make add--interactive more defensive, and say "--no-color" explicitly. It doesn't hurt anything in the common case, but it fixes this odd case and lets our test function properly again. Note that the C builtin run_add_p() already passes --no-color, so it doesn't need a similar fix. That will eventually replace this perl code anyway, but the test change here will be valuable for ensuring that. Signed-off-by: Jeff King Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-add--interactive.perl | 2 +- t/t3701-add-interactive.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index f36c0078ac..b6cdcfef61 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -714,7 +714,7 @@ sub parse_diff { if (defined $patch_mode_revision) { push @diff_cmd, get_diff_reference($patch_mode_revision); } - my @diff = run_cmd_pipe("git", @diff_cmd, "--", $path); + my @diff = run_cmd_pipe("git", @diff_cmd, qw(--no-color --), $path); my @colored = (); if ($diff_use_color) { my @display_cmd = ("git", @diff_cmd, qw(--color --), $path); diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index f0a491ade1..1a24db7fcf 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -573,6 +573,7 @@ test_expect_success 'diffs can be colorized' ' echo content >test && printf y >y && force_color git add -p >output 2>&1