summaryrefslogtreecommitdiff
path: root/builtin/name-rev.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-05-03 21:08:13 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-05-03 21:08:13 (GMT)
commit309ca68e5a11f14491f1b5ad9b0b3384ac4df383 (patch)
tree69e5844ec0a8ad36b704817c60fd126bf1cc47e9 /builtin/name-rev.c
parente61f75fe19250f96003357b3568d81d0e3cf5cc2 (diff)
parent755042480429fbadbb1953416d2c04c035a78e4c (diff)
downloadgit-309ca68e5a11f14491f1b5ad9b0b3384ac4df383.zip
git-309ca68e5a11f14491f1b5ad9b0b3384ac4df383.tar.gz
git-309ca68e5a11f14491f1b5ad9b0b3384ac4df383.tar.bz2
Merge branch 'js/name-rev-use-oldest-ref'
"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
Diffstat (limited to 'builtin/name-rev.c')
-rw-r--r--builtin/name-rev.c19
1 files changed, 13 insertions, 6 deletions
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;
}