From: D. Ben Knoble Date: Sat, 08 Nov 2025 19:08:35 GMT Subject: Re: diff --cached --no-ext-diff --find-copies-harder --quiet exits with wrong status code Message-ID: In-Reply-To: On Sat, Nov 8, 2025 at 2:05 PM D. Ben Knoble wrote: > > AFAICT, you need all of the mentioned options to trigger the bug. > Allowing ext-diff works fine, I don't think it's triggered in > non-cached diffs, and I've never seen it without --find-copies-harder. > Notably, s/quiet/exit-code works just fine. > > Here's a repro from git.git: > > cp git{,1}.c > git add git1.c > git diff --cached --no-ext-diff --quiet --find-copies-harder && > echo 'this should exit 1!' > > (And of course, ^quiet^exit-code if your shell supports it yields a > different outcome) > > Context: my distro applies a patch that allows > diff.renames=copies-harder. In a repo with that turned on, > git-prompt.sh stopped showing some staged changes. Turns out it runs > git diff with all these flags (less --find-copies-harder, which is > enabled by the config option). I _have_ confirmed this bug exists in > unpatched Git, however. > > Some rough debugging notes: when entering diffcore_std (or > diffcore_rename_extended's cleanup loop): > - for exit-code, diff_queued_diff.nr matches "git ls-files :/ | wc -l" > - for quiet, it's just 1 (the first file listed by git ls-files :/, AFAICT) > The only other obvious difference I spotted is that the "quick" flag > is turned on for quiet, which makes sense. Ah, woops. The reason this matters is that, after diff_rename, in the correct version the queue is non-empty and has_changes gets set, which plays into diff_result_code. In the broken version, the resulting queue ends up empty, so has_changes is _reset_ to 0 (despite previously being 1?) I think I also spotted a difference in diff_from_contents, but not sure if that's relevant. -- D. Ben Knoble