threads / patch / 44496

patchrev-parse: fix parent shorthands with --symbolic

Subject: [PATCH] rev-parse: fix parent shorthands with --symbolic

## tl;dr

One message between Nov 16, 2016 and Nov 16, 2016. Diffs are folded; open one to read it.

replies: 0people: 1as markdown or json

Jeff King· Nov 16, 2016, 08:46 UTC · lore

The try_parent_shorthands() function shows each parent via show_rev(). We pass the correct parent sha1, but our "name" parameter still points at the original refname. So asking for a regular rev-parse works fine (it prints the sha1s), but asking for the symbolic name gives nonsense like:

    $ git rev-parse --symbolic HEAD^-1
    HEAD
    ^HEAD

which is always an empty set of commits. Asking for "^!" is likewise broken, with the added bonus that its prints ^HEAD for _each_ parent. And "^@" just prints HEAD repeatedly.

Arguably it would be correct to just pass NULL as the name here, and always get the parent expressed as a sha1. The "--symbolic" documentaton claims only "as close to the original input as possible", and we certainly fallback to sha1s where necessary. But it's pretty easy to generate a symbolic name on the fly from the original.

Signed-off-by: Jeff King <peff@peff.net>
---

I noticed this because tig uses "--symbolic", and "tig 1234abcd^-1" does not work without this patch.

I thought at first it might be a regression in the upcoming v2.11 from 8779351dd (revision: new rev^-n shorthand for rev^n..rev, 2016-09-27). But nope, "^!" has been broken at least as far back as v1.6.6.3 (I didn't check further).

So assuming it's too late in the -rc cycle for a non-regression fix, this is probably post-v2.11 maint material.

 builtin/rev-parse.c          |  7 ++++++-
 t/t6101-rev-parse-parents.sh | 18 ++++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)
Show changes to 2 files +24 −1

builtin/rev-parse.c, t/t6101-rev-parse-parents.sh

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index cfb0f1510..ff13e59e1 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -342,11 +342,16 @@ static int try_parent_shorthands(const char *arg)
 	for (parents = commit->parents, parent_number = 1;
 	     parents;
 	     parents = parents->next, parent_number++) {
+		char *name = NULL;
+
 		if (exclude_parent && parent_number != exclude_parent)
 			continue;
 
+		if (symbolic)
+			name = xstrfmt("%s^%d", arg, parent_number);
 		show_rev(include_parents ? NORMAL : REVERSED,
-			 parents->item->object.oid.hash, arg);
+			 parents->item->object.oid.hash, name);
+		free(name);
 	}
 
 	*dotdot = '^';
diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh
index 64a9850e3..8c617981a 100755
--- a/t/t6101-rev-parse-parents.sh
+++ b/t/t6101-rev-parse-parents.sh
@@ -83,12 +83,24 @@ test_expect_success 'final^1^@ = final^1^1 final^1^2' '
 	test_cmp expect actual
 '
 
+test_expect_success 'symbolic final^1^@ = final^1^1 final^1^2' '
+	git rev-parse --symbolic final^1^1 final^1^2 >expect &&
+	git rev-parse --symbolic final^1^@ >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'final^1^! = final^1 ^final^1^1 ^final^1^2' '
 	git rev-parse final^1 ^final^1^1 ^final^1^2 >expect &&
 	git rev-parse final^1^! >actual &&
 	test_cmp expect actual
 '
 
+test_expect_success 'symbolic final^1^! = final^1 ^final^1^1 ^final^1^2' '
+	git rev-parse --symbolic final^1 ^final^1^1 ^final^1^2 >expect &&
+	git rev-parse --symbolic final^1^! >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'large graft octopus' '
 	test_cmp_rev_output b31 "git rev-parse --verify b1^30"
 '
@@ -143,6 +155,12 @@ test_expect_success 'rev-parse merge^-2 = merge^2..merge' '
 	test_cmp expect actual
 '
 
+test_expect_success 'symbolic merge^-1 = merge^1..merge' '
+	git rev-parse --symbolic merge^1..merge >expect &&
+	git rev-parse --symbolic merge^-1 >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'rev-parse merge^-0 (invalid parent)' '
 	test_must_fail git rev-parse merge^-0
 '
-- 
2.11.0.rc1.280.gf9bb6f9

← back to recent threads