{"thread":{"id":"18845","subject":"[PATCH 1/2] shorten_unambiguous_ref(): add strict mode","startedAt":"2009-04-13T10:25:46Z","lastAt":"2009-04-13T16:43:42Z","messageCount":4,"participants":["Bert Wesarg","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"111171","messageId":"1239618347-17158-1-git-send-email-bert.wesarg@googlemail.com","threadId":"18845","inReplyTo":null,"subject":"[PATCH 1/2] shorten_unambiguous_ref(): add strict mode","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2009-04-13T10:25:46Z","receivedAt":"2009-04-13T10:25:46Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Add the strict mode of abbreviation to shorten_unambiguous_ref(), i.e. the\nresulting ref won't trigger the ambiguous ref warning.\n\nAll users of shorten_unambiguous_ref() still use the loose mode.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\nCc: Jeff King <peff@peff.net>\nCc: git@vger.kernel.org\n\n builtin-branch.c       |    4 ++--\n builtin-for-each-ref.c |    2 +-\n refs.c                 |   18 +++++++++++++++---\n refs.h                 |    2 +-\n 4 files changed, 19 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 3275821..91098ca 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -311,14 +311,14 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,\n \t\tif (branch && branch->merge && branch->merge[0]->dst &&\n \t\t    show_upstream_ref)\n \t\t\tstrbuf_addf(stat, \"[%s] \",\n-\t\t\t    shorten_unambiguous_ref(branch->merge[0]->dst));\n+\t\t\t    shorten_unambiguous_ref(branch->merge[0]->dst, 0));\n \t\treturn;\n \t}\n \n \tstrbuf_addch(stat, '[');\n \tif (show_upstream_ref)\n \t\tstrbuf_addf(stat, \"%s: \",\n-\t\t\tshorten_unambiguous_ref(branch->merge[0]->dst));\n+\t\t\tshorten_unambiguous_ref(branch->merge[0]->dst, 0));\n \tif (!ours)\n \t\tstrbuf_addf(stat, \"behind %d] \", theirs);\n \telse if (!theirs)\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex c8114c8..cfff686 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -601,7 +601,7 @@ static void populate_value(struct refinfo *ref)\n \t\tif (formatp) {\n \t\t\tformatp++;\n \t\t\tif (!strcmp(formatp, \"short\"))\n-\t\t\t\trefname = shorten_unambiguous_ref(refname);\n+\t\t\t\trefname = shorten_unambiguous_ref(refname, 0);\n \t\t\telse\n \t\t\t\tdie(\"unknown %.*s format %s\",\n \t\t\t\t    (int)(formatp - name), name, formatp);\ndiff --git a/refs.c b/refs.c\nindex 82afb87..e65a3b4 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1681,7 +1681,7 @@ static void gen_scanf_fmt(char *scanf_fmt, const char *rule)\n \treturn;\n }\n \n-char *shorten_unambiguous_ref(const char *ref)\n+char *shorten_unambiguous_ref(const char *ref, int strict)\n {\n \tint i;\n \tstatic char **scanf_fmts;\n@@ -1718,6 +1718,7 @@ char *shorten_unambiguous_ref(const char *ref)\n \t/* skip first rule, it will always match */\n \tfor (i = nr_rules - 1; i > 0 ; --i) {\n \t\tint j;\n+\t\tint rules_to_fail = i;\n \t\tint short_name_len;\n \n \t\tif (1 != sscanf(ref, scanf_fmts[i], short_name))\n@@ -1726,14 +1727,25 @@ char *shorten_unambiguous_ref(const char *ref)\n \t\tshort_name_len = strlen(short_name);\n \n \t\t/*\n+\t\t * in strict mode, all (except the matched one) rules\n+\t\t * must fail to resolve to a valid non-ambiguous ref\n+\t\t */\n+\t\tif (strict)\n+\t\t\trules_to_fail = nr_rules;\n+\n+\t\t/*\n \t\t * check if the short name resolves to a valid ref,\n \t\t * but use only rules prior to the matched one\n \t\t */\n-\t\tfor (j = 0; j < i; j++) {\n+\t\tfor (j = 0; j < rules_to_fail; j++) {\n \t\t\tconst char *rule = ref_rev_parse_rules[j];\n \t\t\tunsigned char short_objectname[20];\n \t\t\tchar refname[PATH_MAX];\n \n+\t\t\t/* skip matched rule */\n+\t\t\tif (i == j)\n+\t\t\t\tcontinue;\n+\n \t\t\t/*\n \t\t\t * the short name is ambiguous, if it resolves\n \t\t\t * (with this previous rule) to a valid ref\n@@ -1749,7 +1761,7 @@ char *shorten_unambiguous_ref(const char *ref)\n \t\t * short name is non-ambiguous if all previous rules\n \t\t * haven't resolved to a valid ref\n \t\t */\n-\t\tif (j == i)\n+\t\tif (j == rules_to_fail)\n \t\t\treturn short_name;\n \t}\n \ndiff --git a/refs.h b/refs.h\nindex 50abbbb..29d17a4 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -81,7 +81,7 @@ extern int for_each_reflog(each_ref_fn, void *);\n extern int check_ref_format(const char *target);\n \n extern const char *prettify_ref(const struct ref *ref);\n-extern char *shorten_unambiguous_ref(const char *ref);\n+extern char *shorten_unambiguous_ref(const char *ref, int strict);\n \n /** rename ref, return 0 on success **/\n extern int rename_ref(const char *oldref, const char *newref, const char *logmsg);\n-- \ntg: (c965c02..) bw/short_ref-warnAmbiguousRefs (depends on: master)\n"},{"id":"111172","messageId":"1239618347-17158-2-git-send-email-bert.wesarg@googlemail.com","threadId":"18845","inReplyTo":"1239618347-17158-1-git-send-email-bert.wesarg@googlemail.com","subject":"[PATCH 2/2] for-each-ref: utilize core.warnAmbiguousRefs for :short-format","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2009-04-13T10:25:47Z","receivedAt":"2009-04-13T10:25:47Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"core.warnAmbiguousRefs is used to select strict mode for the\nabbreviation for the \":short\" format specifier of \"refname\" and \"upstream\".\n\nIn strict mode, the abbreviated ref will never trigger the\n'warn_ambiguous_refs' warning. I.e. for these refs:\n\n  refs/heads/xyzzy\n  refs/tags/xyzzy\n\nthe abbreviated forms are:\n\n  heads/xyzzy\n  tags/xyzzy\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n\nCc: \"Jeff King\" <peff@peff.net>\nCc: git@vger.kernel.org\nCc: szeder@ira.uka.de\nCc: \"Shawn O. Pearce\" <spearce@spearce.org>\n\n Documentation/git-for-each-ref.txt |    2 ++\n builtin-for-each-ref.c             |    6 +++++-\n t/t6300-for-each-ref.sh            |   18 +++++++++++++++---\n 3 files changed, 22 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\nindex b362e9e..8dc873f 100644\n--- a/Documentation/git-for-each-ref.txt\n+++ b/Documentation/git-for-each-ref.txt\n@@ -75,6 +75,8 @@ For all objects, the following names can be used:\n refname::\n \tThe name of the ref (the part after $GIT_DIR/).\n \tFor a non-ambiguous short name of the ref append `:short`.\n+\tThe option core.warnAmbiguousRefs is used to select the strict\n+\tabbreviation mode.\n \n objecttype::\n \tThe type of the object (`blob`, `tree`, `commit`, `tag`).\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex cfff686..91e8f95 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -601,7 +601,8 @@ static void populate_value(struct refinfo *ref)\n \t\tif (formatp) {\n \t\t\tformatp++;\n \t\t\tif (!strcmp(formatp, \"short\"))\n-\t\t\t\trefname = shorten_unambiguous_ref(refname, 0);\n+\t\t\t\trefname = shorten_unambiguous_ref(refname,\n+\t\t\t\t\t\t      warn_ambiguous_refs);\n \t\t\telse\n \t\t\t\tdie(\"unknown %.*s format %s\",\n \t\t\t\t    (int)(formatp - name), name, formatp);\n@@ -917,6 +918,9 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \t\tsort = default_sort();\n \tsort_atom_limit = used_atom_cnt;\n \n+\t/* for warn_ambiguous_refs */\n+\tgit_config(git_default_config, NULL);\n+\n \tmemset(&cbdata, 0, sizeof(cbdata));\n \tcbdata.grab_pattern = argv;\n \tfor_each_ref(grab_single_ref, &cbdata);\ndiff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh\nindex daf02d5..8052c86 100755\n--- a/t/t6300-for-each-ref.sh\n+++ b/t/t6300-for-each-ref.sh\n@@ -301,10 +301,11 @@ test_expect_success 'Check for invalid refname format' '\n \n cat >expected <<\\EOF\n heads/master\n-master\n+tags/master\n EOF\n \n-test_expect_success 'Check ambiguous head and tag refs' '\n+test_expect_success 'Check ambiguous head and tag refs (strict)' '\n+\tgit config --bool core.warnambiguousrefs true &&\n \tgit checkout -b newtag &&\n \techo \"Using $datestamp\" > one &&\n \tgit add one &&\n@@ -316,11 +317,22 @@ test_expect_success 'Check ambiguous head and tag refs' '\n '\n \n cat >expected <<\\EOF\n+heads/master\n+master\n+EOF\n+\n+test_expect_success 'Check ambiguous head and tag refs (loose)' '\n+\tgit config --bool core.warnambiguousrefs false &&\n+\tgit for-each-ref --format \"%(refname:short)\" refs/heads/master refs/tags/master >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+cat >expected <<\\EOF\n heads/ambiguous\n ambiguous\n EOF\n \n-test_expect_success 'Check ambiguous head and tag refs II' '\n+test_expect_success 'Check ambiguous head and tag refs II (loose)' '\n \tgit checkout master &&\n \tgit tag ambiguous testtag^0 &&\n \tgit branch ambiguous testtag^0 &&\n-- \ntg: (c4ae76d..) bw/utilize-it (depends on: bw/short_ref-warnAmbiguousRefs)\n"},{"id":"111180","messageId":"1239621626-26952-1-git-send-email-bert.wesarg@googlemail.com","threadId":"18845","inReplyTo":"1239618347-17158-1-git-send-email-bert.wesarg@googlemail.com","subject":"[RFC/PATCH 3/2] rev-parse: --abbrev-ref option to shorten ref name","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2009-04-13T11:20:26Z","receivedAt":"2009-04-13T11:20:26Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"This applies the shorten_unambiguous_ref function to the object name.\nDefault mode is controlled by core.warnAmbiguousRefs. Else it is given as\noptional argument to --abbrev-ref={strict|loose}.\n\nThis should be faster than 'git for-each-ref --format=\"%(refname:short)\" <ref>'\nfor single refs.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\nCc: Jeff King <peff@peff.net>\nCc: git@vger.kernel.org\n\nCan someone check, if I need to alter the filter, thanks.\n\nRegards,\nBert\n\n Documentation/git-rev-parse.txt |    5 +++++\n builtin-rev-parse.c             |   23 +++++++++++++++++++++--\n 2 files changed, 26 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 5ed2bc8..fba30b1 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -84,6 +84,11 @@ OPTIONS\n \tunfortunately named tag \"master\"), and show them as full\n \trefnames (e.g. \"refs/heads/master\").\n \n+--abbrev-ref[={strict|loose}]::\n+\tA non-ambiguous short name of the objects name.\n+\tThe option core.warnAmbiguousRefs is used to select the strict\n+\tabbreviation mode.\n+\n --all::\n \tShow all refs found in `$GIT_DIR/refs`.\n \ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex 81d5a6f..22c6d6a 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -26,6 +26,8 @@ static int show_type = NORMAL;\n #define SHOW_SYMBOLIC_FULL 2\n static int symbolic;\n static int abbrev;\n+static int abbrev_ref;\n+static int abbrev_ref_strict;\n static int output_sq;\n \n /*\n@@ -109,8 +111,8 @@ static void show_rev(int type, const unsigned char *sha1, const char *name)\n \t\treturn;\n \tdef = NULL;\n \n-\tif (symbolic && name) {\n-\t\tif (symbolic == SHOW_SYMBOLIC_FULL) {\n+\tif ((symbolic || abbrev_ref) && name) {\n+\t\tif (symbolic == SHOW_SYMBOLIC_FULL || abbrev_ref) {\n \t\t\tunsigned char discard[20];\n \t\t\tchar *full;\n \n@@ -125,6 +127,9 @@ static void show_rev(int type, const unsigned char *sha1, const char *name)\n \t\t\t\t */\n \t\t\t\tbreak;\n \t\t\tcase 1: /* happy */\n+\t\t\t\tif (abbrev_ref)\n+\t\t\t\t\tfull = shorten_unambiguous_ref(full,\n+\t\t\t\t\t\tabbrev_ref_strict);\n \t\t\t\tshow_with_type(type, full);\n \t\t\t\tbreak;\n \t\t\tdefault: /* ambiguous */\n@@ -506,6 +511,20 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\tsymbolic = SHOW_SYMBOLIC_FULL;\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!prefixcmp(arg, \"--abbrev-ref\") &&\n+\t\t\t    (!arg[12] || arg[12] == '=')) {\n+\t\t\t\tabbrev_ref = 1;\n+\t\t\t\tabbrev_ref_strict = warn_ambiguous_refs;\n+\t\t\t\tif (arg[12] == '=') {\n+\t\t\t\t\tif (!strcmp(arg + 13, \"strict\"))\n+\t\t\t\t\t\tabbrev_ref_strict = 1;\n+\t\t\t\t\telse if (!strcmp(arg + 13, \"loose\"))\n+\t\t\t\t\t\tabbrev_ref_strict = 0;\n+\t\t\t\t\telse\n+\t\t\t\t\t\tdie(\"unknown mode for %s\", arg);\n+\t\t\t\t}\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--all\")) {\n \t\t\t\tfor_each_ref(show_reference, NULL);\n \t\t\t\tcontinue;\n-- \ntg: (5fec79c..) bw/rev-parse_--abbrev_ref (depends on: bw/utilize-it)\n"},{"id":"111198","messageId":"7vhc0sh5c1.fsf@gitster.siamese.dyndns.org","threadId":"18845","inReplyTo":"1239621626-26952-1-git-send-email-bert.wesarg@googlemail.com","subject":"Re: [RFC/PATCH 3/2] rev-parse: --abbrev-ref option to shorten ref name","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-04-13T16:43:42Z","receivedAt":"2009-04-13T16:43:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Bert Wesarg <bert.wesarg@googlemail.com> writes:\n\n> This applies the shorten_unambiguous_ref function to the object name.\n> Default mode is controlled by core.warnAmbiguousRefs. Else it is given as\n> optional argument to --abbrev-ref={strict|loose}.\n>\n> This should be faster than 'git for-each-ref --format=\"%(refname:short)\" <ref>'\n> for single refs.\n>\n> Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n> ---\n> Cc: Jeff King <peff@peff.net>\n> Cc: git@vger.kernel.org\n>\n> Can someone check, if I need to alter the filter, thanks.\n\nI do not think so.\n\nThis --abbrev-ref option is similar to --symbolic in that how a ref from\nthe command line, if any, is output, and should not change the filter at\nall.  For example, \"rev-parse --abbrev-ref master -M\" shouldn't filter -M\nout by implying --revs-only.\n"}]}