Thread (6 messages) 6 messages, 3 authors, 2022-09-28

Re: git diff ^! syntax stopped working for stashes in Git 2.28

From: René Scharfe <hidden>
Date: 2022-09-12 11:16:38
Subsystem: the rest · Maintainer: Linus Torvalds

Am 12.09.22 um 11:57 schrieb Tim Jaacks:
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/ (local)

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);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help