From: Jacob Keller Date: Sun, 20 Sep 2026 23:04:32 GMT Subject: Re: [PATCH] diff --no-index: fix -R with file/directory conflicts Message-ID: <0c82d50e-f2c0-4db6-ade8-7a403cac73da@intel.com> In-Reply-To: On 9/18/2026 12:19 AM, Haokai Ding via GitGitGadget wrote: > From: Haokai Ding > > When a path is a file on one side and a directory on the other, > queue_diff() queues the file separately before recursing into the > directory. This early queue entry bypasses the reverse_diff handling > used for ordinary files. > > As a result, comparing directories d and e where d/sub is a file and > e/sub/file is another file reports both paths as deleted with -R. > Reversing the operands reports both paths as added instead. > > Swap the filespecs of the early queue entry when reverse_diff is set, > so that -R reverses the file change as well as the directory contents. > Add regression tests for both directions. > > Signed-off-by: Haokai Ding > --- Thanks for fixing! Reviewed-by: Jacob Keller > diff --no-index: fix -R with file/directory conflicts > > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2232%2FHaokaiDing%2Ffix%2Fno-index-reverse-file-directory-mail-v1 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2232/HaokaiDing/fix/no-index-reverse-file-directory-mail-v1 > Pull-Request: https://github.com/gitgitgadget/git/pull/2232 > > diff-no-index.c | 2 ++ > t/t4053-diff-no-index.sh | 18 ++++++++++++++++++ > 2 files changed, 20 insertions(+) > > diff --git a/diff-no-index.c b/diff-no-index.c > index f320424f05..a9151cc27a 100644 > --- a/diff-no-index.c > +++ b/diff-no-index.c > @@ -188,6 +188,8 @@ static int queue_diff(struct diff_options *o, const struct git_hash_algo *algop, > mode1 = 0; > } > /* emit that file */ > + if (o->flags.reverse_diff) > + SWAP(d1, d2); > diff_queue(&diff_queued_diff, d1, d2); > > /* and then let the entire directory be created or deleted */ > diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh > index 8e0394cf5a..c3c703f4f4 100755 > --- a/t/t4053-diff-no-index.sh > +++ b/t/t4053-diff-no-index.sh > @@ -120,6 +120,24 @@ test_expect_success 'turning a file into a directory' ' > ) > ' > > +test_expect_success 'reverse diff when turning a file into a directory' ' > + ( > + cd non/git && > + printf "A\td/sub\nD\te/sub/file\n" >expect && > + test_expect_code 1 git diff --no-index -R --name-status d e >actual && > + test_cmp expect actual > + ) > +' > + > +test_expect_success 'reverse diff when turning a directory into a file' ' > + ( > + cd non/git && > + printf "D\td/sub\nA\te/sub/file\n" >expect && > + test_expect_code 1 git diff --no-index -R --name-status e d >actual && > + test_cmp expect actual > + ) > +' > + > test_expect_success 'diff from repo subdir shows real paths (explicit)' ' > echo "diff --git a/../../non/git/a b/../../non/git/b" >expect && > test_expect_code 1 \ > > base-commit: d38352cd43ab9745686d697872408bc3249a153f