Re: git diff ^! syntax stopped working for stashes in Git 2.28
- From
René Scharfe <l.s.r@web.de>
- Date
- Sep 12, 2022, 11:16 UTC
- Message-ID
- <9e0c1a2c-542b-156f-4c70-371d3a9b452d@web.de>
- In-Reply-To
- <6f729c8c43c4409faf6a11a69791f45a@garz-fricke.com>
Am 12.09.22 um 11:57 schrieb Tim Jaacks:
Show 20 quoted lines
> Hello,
>
> I noticed that the following syntax to show the changes of a stash stopped working in Git 2.28:
>
> git diff stash@{0}^!
>
> It still works on commits and HEAD, though:
>
> git diff f27984d^!
> git diff HEAD^!
>
> And diffing against the stash's parent works as well:
>
> git diff stash@{0}^1 stash@{0}
>
> I assume this is a bug. Can anybody confirm this? I verified the behavior change trying different Git versions via docker:
>
> docker run -it --rm --user $(id -u):$(id -g) -v $HOME:$HOME:rw -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v $PWD:$PWD:rw -w $PWD bitnami/git:2.27.0 diff stash@{0}^!
>
> With v2.27.0 the above syntax works, with v2.28.0 and later it doesn't.Bisects to 8bfcb3a690 (git diff: improve range handling, 2020-06-12).
Reverting it partially like in the patch below restores the behavior of "git diff stash@{0}^!". Tests still pass.
A stash revision is a merge. With "stash@{0}^!" it ends up in ent.objects[2] and its parents (marked UNINTERESTING) in ent.objects[0] and ent.objects[1].
I don't know if the current behavior is expected or if the patch is the right fix, but in any case it would need a good explanation that I cannot come up with on the spot.
Copying Chris, author of the mentioned patch. Old discussion thread: https://lore.kernel.org/git/pull.804.git.git.1591661021.gitgitgadget@gmail.com/
René
diff --git a/builtin/diff.c b/builtin/diff.c index 54bb3de964..c34adf2695 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -588,6 +588,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix) sdiff.left, sdiff.right, sdiff.base); result = builtin_diff_tree(&rev, argc, argv, &ent.objects[0], &ent.objects[1]); + } else if (ent.objects[0].item->flags & UNINTERESTING) { + result = builtin_diff_tree(&rev, argc, argv, + &ent.objects[0], + &ent.objects[ent.nr-1]); } else result = builtin_diff_combined(&rev, argc, argv, ent.objects, ent.nr);