Skip to content

Commit 9ee8f94

Browse files
committed
Merge branch 'js/name-rev-use-oldest-ref' into maint
"git describe --contains" often made a hard-to-justify choice of tag to give name to a given commit, because it tried to come up with a name with smallest number of hops from a tag, causing an old commit whose close descendant that is recently tagged were not described with respect to an old tag but with a newer tag. It did not help that its computation of "hop" count was further tweaked to penalize being on a side branch of a merge. The logic has been updated to favor using the tag with the oldest tagger date, which is a lot easier to explain to the end users: "We describe a commit in terms of the (chronologically) oldest tag that contains the commit." * js/name-rev-use-oldest-ref: name-rev: include taggerdate in considering the best name
2 parents b051c59 + 7550424 commit 9ee8f94

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

builtin/name-rev.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
typedef struct rev_name {
1212
const char *tip_name;
13+
unsigned long taggerdate;
1314
int generation;
1415
int distance;
1516
} rev_name;
@@ -20,7 +21,8 @@ static long cutoff = LONG_MAX;
2021
#define MERGE_TRAVERSAL_WEIGHT 65535
2122

2223
static void name_rev(struct commit *commit,
23-
const char *tip_name, int generation, int distance,
24+
const char *tip_name, unsigned long taggerdate,
25+
int generation, int distance,
2426
int deref)
2527
{
2628
struct rev_name *name = (struct rev_name *)commit->util;
@@ -43,9 +45,12 @@ static void name_rev(struct commit *commit,
4345
name = xmalloc(sizeof(rev_name));
4446
commit->util = name;
4547
goto copy_data;
46-
} else if (name->distance > distance) {
48+
} else if (name->taggerdate > taggerdate ||
49+
(name->taggerdate == taggerdate &&
50+
name->distance > distance)) {
4751
copy_data:
4852
name->tip_name = tip_name;
53+
name->taggerdate = taggerdate;
4954
name->generation = generation;
5055
name->distance = distance;
5156
} else
@@ -66,11 +71,11 @@ static void name_rev(struct commit *commit,
6671
new_name = xstrfmt("%.*s^%d", (int)len, tip_name,
6772
parent_number);
6873

69-
name_rev(parents->item, new_name, 0,
74+
name_rev(parents->item, new_name, taggerdate, 0,
7075
distance + MERGE_TRAVERSAL_WEIGHT, 0);
7176
} else {
72-
name_rev(parents->item, tip_name, generation + 1,
73-
distance + 1, 0);
77+
name_rev(parents->item, tip_name, taggerdate,
78+
generation + 1, distance + 1, 0);
7479
}
7580
}
7681
}
@@ -140,6 +145,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
140145
struct name_ref_data *data = cb_data;
141146
int can_abbreviate_output = data->tags_only && data->name_only;
142147
int deref = 0;
148+
unsigned long taggerdate = ULONG_MAX;
143149

144150
if (data->tags_only && !starts_with(path, "refs/tags/"))
145151
return 0;
@@ -164,12 +170,13 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
164170
break; /* broken repository */
165171
o = parse_object(t->tagged->oid.hash);
166172
deref = 1;
173+
taggerdate = t->date;
167174
}
168175
if (o && o->type == OBJ_COMMIT) {
169176
struct commit *commit = (struct commit *)o;
170177

171178
path = name_ref_abbrev(path, can_abbreviate_output);
172-
name_rev(commit, xstrdup(path), 0, 0, deref);
179+
name_rev(commit, xstrdup(path), taggerdate, 0, 0, deref);
173180
}
174181
return 0;
175182
}

t/t9903-bash-prompt.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ test_expect_success 'prompt - describe detached head - contains' '
107107
'
108108

109109
test_expect_success 'prompt - describe detached head - branch' '
110-
printf " ((b1~1))" >expected &&
110+
printf " ((tags/t2~1))" >expected &&
111111
git checkout b1^ &&
112112
test_when_finished "git checkout master" &&
113113
(

0 commit comments

Comments
 (0)