threads / patch / 42107

patchname-rev: include taggerdate in considering the best name

Subject: [PATCH] name-rev: include taggerdate in considering the best name

## tl;dr

7 messages between Apr 22, 2016 and Apr 24, 2016. Diffs are folded; open one to read it.

replies: 6people: 4as markdown or json

Johannes Schindelin· Apr 22, 2016, 13:39 UTC · lore

We most likely want the oldest tag that contained the commit to be reported. So let's remember the taggerdate, and make it more important than anything else when choosing the best name for a given commit.

Suggested by Linus Torvalds.

Note that we need to update t9903 because it tested for the old behavior (which preferred the description "b1~1" over "tags/t2~1").

We might want to introduce a --heed-taggerdate option, and make the new behavior dependent on that, if it turns out that some scripts rely on the old name-rev method.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/name-rev.c     | 19 +++++++++++++------
 t/t9903-bash-prompt.sh |  2 +-
 2 files changed, 14 insertions(+), 7 deletions(-)
Show changes to 2 files +14 −7

builtin/name-rev.c, t/t9903-bash-prompt.sh

diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 092e03c..57be35f 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -10,6 +10,7 @@
 
 typedef struct rev_name {
 	const char *tip_name;
+	unsigned long taggerdate;
 	int generation;
 	int distance;
 } rev_name;
@@ -20,7 +21,8 @@ static long cutoff = LONG_MAX;
 #define MERGE_TRAVERSAL_WEIGHT 65535
 
 static void name_rev(struct commit *commit,
-		const char *tip_name, int generation, int distance,
+		const char *tip_name, unsigned long taggerdate,
+		int generation, int distance,
 		int deref)
 {
 	struct rev_name *name = (struct rev_name *)commit->util;
@@ -43,9 +45,12 @@ static void name_rev(struct commit *commit,
 		name = xmalloc(sizeof(rev_name));
 		commit->util = name;
 		goto copy_data;
-	} else if (name->distance > distance) {
+	} else if (name->taggerdate > taggerdate ||
+			(name->taggerdate == taggerdate &&
+			 name->distance > distance)) {
 copy_data:
 		name->tip_name = tip_name;
+		name->taggerdate = taggerdate;
 		name->generation = generation;
 		name->distance = distance;
 	} else
@@ -66,11 +71,11 @@ copy_data:
 				new_name = xstrfmt("%.*s^%d", (int)len, tip_name,
 						   parent_number);
 
-			name_rev(parents->item, new_name, 0,
+			name_rev(parents->item, new_name, taggerdate, 0,
 				distance + MERGE_TRAVERSAL_WEIGHT, 0);
 		} else {
-			name_rev(parents->item, tip_name, generation + 1,
-				distance + 1, 0);
+			name_rev(parents->item, tip_name, taggerdate,
+				generation + 1, distance + 1, 0);
 		}
 	}
 }
@@ -140,6 +145,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
 	struct name_ref_data *data = cb_data;
 	int can_abbreviate_output = data->tags_only && data->name_only;
 	int deref = 0;
+	unsigned long taggerdate = ULONG_MAX;
 
 	if (data->tags_only && !starts_with(path, "refs/tags/"))
 		return 0;
@@ -164,12 +170,13 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
 			break; /* broken repository */
 		o = parse_object(t->tagged->oid.hash);
 		deref = 1;
+		taggerdate = t->date;
 	}
 	if (o && o->type == OBJ_COMMIT) {
 		struct commit *commit = (struct commit *)o;
 
 		path = name_ref_abbrev(path, can_abbreviate_output);
-		name_rev(commit, xstrdup(path), 0, 0, deref);
+		name_rev(commit, xstrdup(path), taggerdate, 0, 0, deref);
 	}
 	return 0;
 }
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index ffbfa0e..0db4469 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -107,7 +107,7 @@ test_expect_success 'prompt - describe detached head - contains' '
 '
 
 test_expect_success 'prompt - describe detached head - branch' '
-	printf " ((b1~1))" >expected &&
+	printf " ((tags/t2~1))" >expected &&
 	git checkout b1^ &&
 	test_when_finished "git checkout master" &&
 	(
-- 
2.8.1.207.g7b140d3
Jeff King· Apr 22, 2016, 18:11 UTC · re: Johannes Schindelin · lore

Re: [PATCH] name-rev: include taggerdate in considering the best name

On Fri, Apr 22, 2016 at 03:39:01PM +0200, Johannes Schindelin wrote:
Show 18 quoted lines
> We most likely want the oldest tag that contained the commit to be
> reported. So let's remember the taggerdate, and make it more important
> than anything else when choosing the best name for a given commit.
> 
> Suggested by Linus Torvalds.
> 
> Note that we need to update t9903 because it tested for the old behavior
> (which preferred the description "b1~1" over "tags/t2~1").
> 
> We might want to introduce a --heed-taggerdate option, and make the new
> behavior dependent on that, if it turns out that some scripts rely on the
> old name-rev method.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  builtin/name-rev.c     | 19 +++++++++++++------
>  t/t9903-bash-prompt.sh |  2 +-
>  2 files changed, 14 insertions(+), 7 deletions(-)

That turned out to be quite simple (I wasn't sure originally if we'd actually visit all of the tags, which is why I had conceived of this as an initial pass; but of course it makes sense that we'd have to see all of the tags in the existing code).

I confirmed that it does find the "optimal" tag for the case we've been discussing.

We could _also_ tweak the merge-weight as Linus's patch did, just because 10000 has more basis than 65535. But I think it really matters a lot less at this point.

-Peff
Junio C Hamano· Apr 22, 2016, 18:27 UTC · re: Jeff King · lore

Re: [PATCH] name-rev: include taggerdate in considering the best name

Jeff King <peff@peff.net> writes:
Show 8 quoted lines
> That turned out to be quite simple (I wasn't sure originally if we'd
> actually visit all of the tags, which is why I had conceived of this as
> an initial pass; but of course it makes sense that we'd have to see all
> of the tags in the existing code).
> ...
> We could _also_ tweak the merge-weight as Linus's patch did, just
> because 10000 has more basis than 65535. But I think it really matters a
> lot less at this point.

I agree, but if we were to go this route of keeping track of "some" attribute of the tip the traversal started from, I wonder if it is better to keep the actual tag object, not just its tagger date as an unsigned long, in the new field.

That way, a tweak may be able to even use the v:refname comparison if we wanted to do so in the future. It is easy to go from a tag object to its tagger date, but it is impossible to go in the other direction, i.e. given a tagger date to go back to the tag.

Junio C Hamano· Apr 22, 2016, 18:40 UTC · re: Junio C Hamano · lore

Re: [PATCH] name-rev: include taggerdate in considering the best name

Junio C Hamano <gitster@pobox.com> writes:
Show 15 quoted lines
> Jeff King <peff@peff.net> writes:
>
>> That turned out to be quite simple (I wasn't sure originally if we'd
>> actually visit all of the tags, which is why I had conceived of this as
>> an initial pass; but of course it makes sense that we'd have to see all
>> of the tags in the existing code).
>> ...
>> We could _also_ tweak the merge-weight as Linus's patch did, just
>> because 10000 has more basis than 65535. But I think it really matters a
>> lot less at this point.
>
> I agree, but if we were to go this route of keeping track of "some"
> attribute of the tip the traversal started from, I wonder if it is
> better to keep the actual tag object, not just its tagger date as an
> unsigned long, in the new field.

Actually, I take it back. The "object" approach would not give us enough flexibility to go beyond "date". A light-weight tag that directly point at a commit object can still yield "date" (probably "committerdate" to be compared with other dates, be it the committer date from another commit or the tagger date from a real tag), but if we later wanted to do a v:refname kind of comparison, we'd need to keep the name of the ref (we cannot go back from the commit object to the refname), so at that point, we would be talking about adding yet another field anyway to hold the refname, in addition to the field we would be adding at this step. As we do not want to be always doing "name to object to date" conversion in this codepath, adding an "unsigned long" date field is the right thing to do here. A more elaborate future can add refname (or refname and object) as additional fields, but we can wait because even after that update the codepath to do date comparison likely would want to have direct access to the date field anyway.

Linus Torvalds· Apr 22, 2016, 18:45 UTC · re: Jeff King · lore

Re: [PATCH] name-rev: include taggerdate in considering the best name

On Fri, Apr 22, 2016 at 11:11 AM, Jeff King <peff@peff.net> wrote:
>
> I confirmed that it does find the "optimal" tag for the case we've been
> discussing.

Yes. I'm a bit more worried about the date behavior for projects that merge back stable branches into their development trees (is the development tag better than the stable tag? the date doesn't really say much), but I think this is still the simplest model we can use without trying to really do a topo-sort. And in many ways it's the simplest one to explain to people too: "we try to use the oldest reference we can find as a base for the resulting name" is not a complex or hard concept to explain.

> We could _also_ tweak the merge-weight as Linus's patch did, just
> because 10000 has more basis than 65535. But I think it really matters a
> lot less at this point.

Yes. I still think that my tweak makes more sense than the existing code, but it's a tiny tweak, compared to the date-based approach. Unlikely to ever matter much.

            Linus
Junio C Hamano· Apr 22, 2016, 20:50 UTC · re: Linus Torvalds · lore

Re: [PATCH] name-rev: include taggerdate in considering the best name

Linus Torvalds <torvalds@linux-foundation.org> writes:
Show 5 quoted lines
> ... I think this is still the simplest model we can use
> without trying to really do a topo-sort. And in many ways it's the
> simplest one to explain to people too: "we try to use the oldest
> reference we can find as a base for the resulting name" is not a
> complex or hard concept to explain.

Yes, the more I look at Dscho's patch, the more like it exactly for that reason. Its behaviour is very simple from the end-user's point of view, unlike the historical one.

Johannes Schindelin· Apr 24, 2016, 06:35 UTC · re: Junio C Hamano · lore

Re: [PATCH] name-rev: include taggerdate in considering the best name

Hi,

[fixing Uwe's email address, as the address bounces that was recorded in the commit introducing the flawed behavior, and I failed to check mailmap earlier.]

On Fri, 22 Apr 2016, Junio C Hamano wrote:
Show 11 quoted lines
> Linus Torvalds <torvalds@linux-foundation.org> writes:
> 
> > ... I think this is still the simplest model we can use
> > without trying to really do a topo-sort. And in many ways it's the
> > simplest one to explain to people too: "we try to use the oldest
> > reference we can find as a base for the resulting name" is not a
> > complex or hard concept to explain.
> 
> Yes, the more I look at Dscho's patch, the more like it exactly for
> that reason.  Its behaviour is very simple from the end-user's point
> of view, unlike the historical one.
Well, seeing as I introduced the bug, it's only fair that I fix it, too.

Ciao, Dscho

← back to recent threads