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 <bert.wesarg@xxxxxxxxxxxxxx> --- Cc: Jeff King <peff@xxxxxxxx> Cc: git@xxxxxxxxxxxxxxx builtin-branch.c | 4 ++-- builtin-for-each-ref.c | 2 +- refs.c | 18 +++++++++++++++--- refs.h | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/builtin-branch.c b/builtin-branch.c index 3275821..91098ca 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 c8114c8..cfff686 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 82afb87..e65a3b4 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)) @@ -1726,14 +1727,25 @@ 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 50abbbb..29d17a4 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); -- tg: (c965c02..) bw/short_ref-warnAmbiguousRefs (depends on: master) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html