提交 cf69fd49 编写于 作者: S Shawn O. Pearce 提交者: Junio C Hamano

Correct priority of lightweight tags in git-describe.

We really want to always favor an annotated tag over a lightweight
tag when describing a commit.  Unfortunately git-describe wasn't
doing this as it was favoring the depth attribute of a possible_tag
over the priority.  Now priority is the highest sort and we only
consider a lightweight tag if no annotated tags were identified.

Rather than searching for the minimum tag using a simple loop we
now sort them using a stable sort algorithm, this way the possible
tags display in order if --debug gets used.  The stable sort helps
to preseve the inherit topology/date order that we obtain during
our search loop.

This fix allows the tests in t6120-describe.sh to pass.
Signed-off-by: NShawn O. Pearce <spearce@spearce.org>
Signed-off-by: NJunio C Hamano <junkio@cox.net>
上级 5312ab11
...@@ -22,6 +22,9 @@ static struct commit_name { ...@@ -22,6 +22,9 @@ static struct commit_name {
int prio; /* annotated tag = 2, tag = 1, head = 0 */ int prio; /* annotated tag = 2, tag = 1, head = 0 */
char path[FLEX_ARRAY]; /* more */ char path[FLEX_ARRAY]; /* more */
} **name_array[256]; } **name_array[256];
static const char *prio_names[] = {
"head", "lightweight", "annotated",
};
static struct commit_name *match(struct commit *cmit) static struct commit_name *match(struct commit *cmit)
{ {
...@@ -118,10 +121,24 @@ static int compare_names(const void *_a, const void *_b) ...@@ -118,10 +121,24 @@ static int compare_names(const void *_a, const void *_b)
struct possible_tag { struct possible_tag {
struct commit_name *name; struct commit_name *name;
unsigned long depth; int depth;
int found_order;
unsigned flag_within; unsigned flag_within;
}; };
static int compare_pt(const void *a_, const void *b_)
{
struct possible_tag *a = (struct possible_tag *)a_;
struct possible_tag *b = (struct possible_tag *)b_;
if (a->name->prio != b->name->prio)
return b->name->prio - a->name->prio;
if (a->depth != b->depth)
return a->depth - b->depth;
if (a->found_order != b->found_order)
return a->found_order - b->found_order;
return 0;
}
static void describe(const char *arg, int last_one) static void describe(const char *arg, int last_one)
{ {
unsigned char sha1[20]; unsigned char sha1[20];
...@@ -129,9 +146,10 @@ static void describe(const char *arg, int last_one) ...@@ -129,9 +146,10 @@ static void describe(const char *arg, int last_one)
struct commit_list *list; struct commit_list *list;
static int initialized = 0; static int initialized = 0;
struct commit_name *n; struct commit_name *n;
struct possible_tag all_matches[MAX_TAGS], *min_match; struct possible_tag all_matches[MAX_TAGS];
unsigned int match_cnt = 0, annotated_cnt = 0, cur_match; unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
unsigned long seen_commits = 0; unsigned long seen_commits = 0;
int found = 0;
if (get_sha1(arg, sha1)) if (get_sha1(arg, sha1))
die("Not a valid object name %s", arg); die("Not a valid object name %s", arg);
...@@ -171,6 +189,7 @@ static void describe(const char *arg, int last_one) ...@@ -171,6 +189,7 @@ static void describe(const char *arg, int last_one)
t->name = n; t->name = n;
t->depth = seen_commits - 1; t->depth = seen_commits - 1;
t->flag_within = 1u << match_cnt; t->flag_within = 1u << match_cnt;
t->found_order = found++;
c->object.flags |= t->flag_within; c->object.flags |= t->flag_within;
if (n->prio == 2) if (n->prio == 2)
annotated_cnt++; annotated_cnt++;
...@@ -205,18 +224,12 @@ static void describe(const char *arg, int last_one) ...@@ -205,18 +224,12 @@ static void describe(const char *arg, int last_one)
if (!match_cnt) if (!match_cnt)
die("cannot describe '%s'", sha1_to_hex(cmit->object.sha1)); die("cannot describe '%s'", sha1_to_hex(cmit->object.sha1));
min_match = &all_matches[0]; qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
for (cur_match = 1; cur_match < match_cnt; cur_match++) {
struct possible_tag *t = &all_matches[cur_match];
if (t->depth < min_match->depth
&& t->name->prio >= min_match->name->prio)
min_match = t;
}
if (debug) { if (debug) {
for (cur_match = 0; cur_match < match_cnt; cur_match++) { for (cur_match = 0; cur_match < match_cnt; cur_match++) {
struct possible_tag *t = &all_matches[cur_match]; struct possible_tag *t = &all_matches[cur_match];
fprintf(stderr, " %c %8lu %s\n", fprintf(stderr, " %-11s %8d %s\n",
min_match == t ? '*' : ' ', prio_names[t->name->prio],
t->depth, t->name->path); t->depth, t->name->path);
} }
fprintf(stderr, "traversed %lu commits\n", seen_commits); fprintf(stderr, "traversed %lu commits\n", seen_commits);
...@@ -228,7 +241,7 @@ static void describe(const char *arg, int last_one) ...@@ -228,7 +241,7 @@ static void describe(const char *arg, int last_one)
sha1_to_hex(gave_up_on->object.sha1)); sha1_to_hex(gave_up_on->object.sha1));
} }
} }
printf("%s-g%s\n", min_match->name->path, printf("%s-g%s\n", all_matches[0].name->path,
find_unique_abbrev(cmit->object.sha1, abbrev)); find_unique_abbrev(cmit->object.sha1, abbrev));
if (!last_one) if (!last_one)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册