From: Bert Wesarg Date: Mon, 13 Apr 2009 10:25:46 +0000 (+0200) Subject: shorten_unambiguous_ref(): add strict mode X-Git-Tag: v1.6.3-rc1~12^2~3 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=6e7b3309d356077337b8222683a743c27fa7276c;p=git.git shorten_unambiguous_ref(): add strict mode Add the strict mode of abbreviation to shorten_unambiguous_ref(), i.e. the resulting ref won't trigger the ambiguous ref warning. All users of shorten_unambiguous_ref() still use the loose mode. Signed-off-by: Bert Wesarg Signed-off-by: Junio C Hamano --- diff --git a/builtin-branch.c b/builtin-branch.c index 327582169..91098ca9b 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -311,14 +311,14 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name, if (branch && branch->merge && branch->merge[0]->dst && show_upstream_ref) strbuf_addf(stat, "[%s] ", - shorten_unambiguous_ref(branch->merge[0]->dst)); + shorten_unambiguous_ref(branch->merge[0]->dst, 0)); return; } strbuf_addch(stat, '['); if (show_upstream_ref) strbuf_addf(stat, "%s: ", - shorten_unambiguous_ref(branch->merge[0]->dst)); + shorten_unambiguous_ref(branch->merge[0]->dst, 0)); if (!ours) strbuf_addf(stat, "behind %d] ", theirs); else if (!theirs) diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index c8114c8af..cfff686ac 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -601,7 +601,7 @@ static void populate_value(struct refinfo *ref) if (formatp) { formatp++; if (!strcmp(formatp, "short")) - refname = shorten_unambiguous_ref(refname); + refname = shorten_unambiguous_ref(refname, 0); else die("unknown %.*s format %s", (int)(formatp - name), name, formatp); diff --git a/refs.c b/refs.c index 82afb8768..e65a3b4c4 100644 --- a/refs.c +++ b/refs.c @@ -1681,7 +1681,7 @@ static void gen_scanf_fmt(char *scanf_fmt, const char *rule) return; } -char *shorten_unambiguous_ref(const char *ref) +char *shorten_unambiguous_ref(const char *ref, int strict) { int i; static char **scanf_fmts; @@ -1718,6 +1718,7 @@ char *shorten_unambiguous_ref(const char *ref) /* skip first rule, it will always match */ for (i = nr_rules - 1; i > 0 ; --i) { int j; + int rules_to_fail = i; int short_name_len; if (1 != sscanf(ref, scanf_fmts[i], short_name)) @@ -1725,15 +1726,26 @@ char *shorten_unambiguous_ref(const char *ref) short_name_len = strlen(short_name); + /* + * in strict mode, all (except the matched one) rules + * must fail to resolve to a valid non-ambiguous ref + */ + if (strict) + rules_to_fail = nr_rules; + /* * check if the short name resolves to a valid ref, * but use only rules prior to the matched one */ - for (j = 0; j < i; j++) { + for (j = 0; j < rules_to_fail; j++) { const char *rule = ref_rev_parse_rules[j]; unsigned char short_objectname[20]; char refname[PATH_MAX]; + /* skip matched rule */ + if (i == j) + continue; + /* * the short name is ambiguous, if it resolves * (with this previous rule) to a valid ref @@ -1749,7 +1761,7 @@ char *shorten_unambiguous_ref(const char *ref) * short name is non-ambiguous if all previous rules * haven't resolved to a valid ref */ - if (j == i) + if (j == rules_to_fail) return short_name; } diff --git a/refs.h b/refs.h index 50abbbb2a..29d17a48e 100644 --- a/refs.h +++ b/refs.h @@ -81,7 +81,7 @@ extern int for_each_reflog(each_ref_fn, void *); extern int check_ref_format(const char *target); extern const char *prettify_ref(const struct ref *ref); -extern char *shorten_unambiguous_ref(const char *ref); +extern char *shorten_unambiguous_ref(const char *ref, int strict); /** rename ref, return 0 on success **/ extern int rename_ref(const char *oldref, const char *newref, const char *logmsg);