{"thread":{"id":"33690","subject":"[PATCH/RFC] get_sha1: prefer 40-hex ref name over 40-hex SHA-1","startedAt":"2013-05-01T03:01:22Z","lastAt":"2013-05-29T12:12:42Z","messageCount":8,"participants":["Nguyễn Thái Ngọc Duy","Eric Sunshine","Jonathan Nieder","Thomas Rast","Duy Nguyen","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"216119","messageId":"1367377282-9862-1-git-send-email-pclouds@gmail.com","threadId":"33690","inReplyTo":null,"subject":"[PATCH/RFC] get_sha1: prefer 40-hex ref name over 40-hex SHA-1","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-05-01T03:01:22Z","receivedAt":"2013-05-01T03:01:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The current behavior is inconsistent when passing SHA-1 to get_sha1.\nIf it's a short sha-1, refs take precedence. \"git rev-parse 1234\" will\nresolve refs/heads/1234 if exists even if there is an unambiguous\nSHA-1 starting with 1234. However if it's full SHA-1, the SHA-1 takes\nprecedence and refs with the same name are ignored.\n\nThe former makes more sense than the latter. This patch makes git\ncheck for 40-hex ref names before consider it SHA-1. In future, we may\nwant to warn ambiguity between refs and SHA-1 (for both full and short\nSHA-1).\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Some gray area where my \"makes more sense\" may not actually be common\n sense.\n\n sha1_name.c                         | 13 +++++++++++--\n t/t1512-rev-parse-disambiguation.sh | 15 +++++++++++++++\n 2 files changed, 26 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 3820f28..faf10b4 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -436,11 +436,20 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n {\n \tstatic const char *warn_msg = \"refname '%.*s' is ambiguous.\";\n \tchar *real_ref = NULL;\n-\tint refs_found = 0;\n+\tint refs_found;\n \tint at, reflog_len;\n \n-\tif (len == 40 && !get_sha1_hex(str, sha1))\n+\tif (len == 40 && !get_sha1_hex(str, sha1)) {\n+\t\tunsigned char ref_sha1[20];\n+\t\trefs_found = dwim_ref(str, len, ref_sha1, &real_ref);\n+\t\tif (refs_found > 0) {\n+\t\t\tif (warn_ambiguous_refs && refs_found > 1)\n+\t\t\t\twarning(warn_msg, len, str);\n+\t\t\thashcpy(sha1, ref_sha1);\n+\t\t}\n+\t\tfree(real_ref);\n \t\treturn 0;\n+\t}\n \n \t/* basic@{time or number or -number} format to query ref-log */\n \treflog_len = at = 0;\ndiff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh\nindex 6b3d797..97ff8ac 100755\n--- a/t/t1512-rev-parse-disambiguation.sh\n+++ b/t/t1512-rev-parse-disambiguation.sh\n@@ -261,4 +261,19 @@ test_expect_success 'rev-parse --disambiguate' '\n \ttest \"$(sed -e \"s/^\\(.........\\).*/\\1/\" actual | sort -u)\" = 000000000\n '\n \n+test_expect_success 'rev-parse 20-hex ref' '\n+\tREF=`git rev-parse HEAD` &&\n+\tVAL=`echo| git commit-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904` &&\n+\tgit update-ref refs/heads/$REF $VAL &&\n+\ttest `git rev-parse $REF` = $VAL\n+'\n+\n+test_expect_success 'rev-parse ambiguous 20-hex ref' '\n+\tREF=`git rev-parse HEAD` &&\n+\tVAL=`echo| git commit-tree -p HEAD 4b825dc642cb6eb9a060e54bf8d69288fbee4904` &&\n+\tgit update-ref refs/tags/$REF $VAL &&\n+\ttest `git rev-parse $REF 2>err` = $VAL &&\n+\tgrep \"refname.*ambiguous\" err\n+'\n+\n test_done\n-- \n1.8.2.83.gc99314b\n"},{"id":"216120","messageId":"CAPig+cQMN56KfcgAu5EO39aGYwL_TO8CWuHSfcwAbruzw0a88A@mail.gmail.com","threadId":"33690","inReplyTo":"1367377282-9862-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH/RFC] get_sha1: prefer 40-hex ref name over 40-hex SHA-1","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-05-01T03:03:03Z","receivedAt":"2013-05-01T03:03:03Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Apr 30, 2013 at 11:01 PM, Nguyễn Thái Ngọc Duy\n<pclouds@gmail.com> wrote:\n> The current behavior is inconsistent when passing SHA-1 to get_sha1.\n> If it's a short sha-1, refs take precedence. \"git rev-parse 1234\" will\n> resolve refs/heads/1234 if exists even if there is an unambiguous\n> SHA-1 starting with 1234. However if it's full SHA-1, the SHA-1 takes\n> precedence and refs with the same name are ignored.\n>\n> The former makes more sense than the latter. This patch makes git\n> check for 40-hex ref names before consider it SHA-1. In future, we may\n> want to warn ambiguity between refs and SHA-1 (for both full and short\n\ns/warn/warn about/\n\n> SHA-1).\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n"},{"id":"216173","messageId":"20130501184327.GM24467@google.com","threadId":"33690","inReplyTo":"1367377282-9862-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH/RFC] get_sha1: prefer 40-hex ref name over 40-hex SHA-1","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2013-05-01T18:43:27Z","receivedAt":"2013-05-01T18:43:27Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyễn Thái Ngọc Duy wrote:\n\n>                                              \"git rev-parse 1234\" will\n> resolve refs/heads/1234 if exists even if there is an unambiguous\n> SHA-1 starting with 1234. However if it's full SHA-1, the SHA-1 takes\n> precedence and refs with the same name are ignored.\n\nThat's an important feature for safety.  When a script has created an\nobject or learned about it some other way, as long as it doesn't\nabbreviate its name it can be sure that git commands will not\nmisunderstand it.\n\nSo I think this is a bad change.  Maybe check-ref-format should\nreject 40-hexdigit refnames?\n\n[...]\n> --- a/t/t1512-rev-parse-disambiguation.sh\n> +++ b/t/t1512-rev-parse-disambiguation.sh\n> @@ -261,4 +261,19 @@ test_expect_success 'rev-parse --disambiguate' '\n>  \ttest \"$(sed -e \"s/^\\(.........\\).*/\\1/\" actual | sort -u)\" = 000000000\n>  '\n>  \n> +test_expect_success 'rev-parse 20-hex ref' '\n> +\tREF=`git rev-parse HEAD` &&\n> +\tVAL=`echo| git commit-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904` &&\n> +\tgit update-ref refs/heads/$REF $VAL &&\n> +\ttest `git rev-parse $REF` = $VAL\n> +'\n\nThis is a good thing to test.  Nit: outside of t0000, please use\n\n\tempty_tree=$(git mktree </dev/null) &&\n\ninstead of hard-coding the hash.  Otherwise you are making my life\nhard when I write md5git. :)  And more importantly, this makes the\nmeaning of the test easier to understand by reading it.\n\nThanks,\nJonathan\n"},{"id":"216235","messageId":"87r4hpu5f8.fsf@linux-k42r.v.cablecom.net","threadId":"33690","inReplyTo":"1367377282-9862-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH/RFC] get_sha1: prefer 40-hex ref name over 40-hex SHA-1","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-05-02T08:55:39Z","receivedAt":"2013-05-02T08:55:39Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:\n\n> +test_expect_success 'rev-parse 20-hex ref' '\n> +\tREF=`git rev-parse HEAD` &&\n> +\tVAL=`echo| git commit-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904` &&\n> +\tgit update-ref refs/heads/$REF $VAL &&\n> +\ttest `git rev-parse $REF` = $VAL\n> +'\n> +\n> +test_expect_success 'rev-parse ambiguous 20-hex ref' '\n> +\tREF=`git rev-parse HEAD` &&\n> +\tVAL=`echo| git commit-tree -p HEAD 4b825dc642cb6eb9a060e54bf8d69288fbee4904` &&\n> +\tgit update-ref refs/tags/$REF $VAL &&\n> +\ttest `git rev-parse $REF 2>err` = $VAL &&\n> +\tgrep \"refname.*ambiguous\" err\n> +'\n\nShouldn't these say s/20-hex/40-hex/?\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"216241","messageId":"CACsJy8AOEEAJ6jtcaAWmrfCbejq8SLcEsUNSsrOEJ6he+5CByA@mail.gmail.com","threadId":"33690","inReplyTo":"20130501184327.GM24467@google.com","subject":"Re: [PATCH/RFC] get_sha1: prefer 40-hex ref name over 40-hex SHA-1","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2013-05-02T10:09:29Z","receivedAt":"2013-05-02T10:09:29Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, May 2, 2013 at 1:43 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Nguyễn Thái Ngọc Duy wrote:\n>\n>>                                              \"git rev-parse 1234\" will\n>> resolve refs/heads/1234 if exists even if there is an unambiguous\n>> SHA-1 starting with 1234. However if it's full SHA-1, the SHA-1 takes\n>> precedence and refs with the same name are ignored.\n>\n> That's an important feature for safety.  When a script has created an\n> object or learned about it some other way, as long as it doesn't\n> abbreviate its name it can be sure that git commands will not\n> misunderstand it.\n\nThen what about abbrev sha-1? You pick up an abbrev sha-1 from \"git\nlog --oneline\", do \"git show <abbrev>\". If you happen to have\nrefs/heads/<abbrev> then what you see is not what you intend to see.\nWarn about ambiguity and move on? Banning all sha1-alike refs seems\nunreasonable (or not? I don't know).\n\n> So I think this is a bad change.  Maybe check-ref-format should\n> reject 40-hexdigit refnames?\n\nI tried that first. The test suite screamed. Will do that again and\nfigure out soon.\n--\nDuy\n"},{"id":"216400","messageId":"1367639113-17342-1-git-send-email-pclouds@gmail.com","threadId":"33690","inReplyTo":"20130501184327.GM24467@google.com","subject":"[PATCH] get_sha1: improve ambiguity warning regarding SHA-1 and ref names","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-05-04T03:45:13Z","receivedAt":"2013-05-04T03:45:13Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"When we get 40 hex digits, we immediately assume it's an SHA-1. Warn\nabout ambiguity if there's also refs/heads/$sha1 (or similar) on system.\n\nWhen we successfully resolve a ref like \"1234abc\" and \"1234abc\"\nhappens to be valid abbreviated SHA-1 on system, warn also.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n On Thu, May 2, 2013 at 1:43 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n > Nguyễn Thái Ngọc Duy wrote:\n >\n >>                                              \"git rev-parse 1234\" will\n >> resolve refs/heads/1234 if exists even if there is an unambiguous\n >> SHA-1 starting with 1234. However if it's full SHA-1, the SHA-1 takes\n >> precedence and refs with the same name are ignored.\n >\n > That's an important feature for safety.  When a script has created an\n > object or learned about it some other way, as long as it doesn't\n > abbreviate its name it can be sure that git commands will not\n > misunderstand it.\n >\n > So I think this is a bad change.  Maybe check-ref-format should\n > reject 40-hexdigit refnames?\n\n We can't, at least not in a simple way, because there are 40-hex\n digit refs in refs/replace. I think warning only is a simpler\n approach to this minor issue.\n\n sha1_name.c                         | 12 ++++++++++--\n t/t1512-rev-parse-disambiguation.sh | 18 ++++++++++++++++++\n 2 files changed, 28 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 3820f28..04a9fbe 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -435,12 +435,18 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l\n static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n {\n \tstatic const char *warn_msg = \"refname '%.*s' is ambiguous.\";\n+\tunsigned char tmp_sha1[20];\n \tchar *real_ref = NULL;\n \tint refs_found = 0;\n \tint at, reflog_len;\n \n-\tif (len == 40 && !get_sha1_hex(str, sha1))\n+\tif (len == 40 && !get_sha1_hex(str, sha1)) {\n+\t\trefs_found = dwim_ref(str, len, tmp_sha1, &real_ref);\n+\t\tif (refs_found > 0 && warn_ambiguous_refs)\n+\t\t\twarning(warn_msg, len, str);\n+\t\tfree(real_ref);\n \t\treturn 0;\n+\t}\n \n \t/* basic@{time or number or -number} format to query ref-log */\n \treflog_len = at = 0;\n@@ -481,7 +487,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n \tif (!refs_found)\n \t\treturn -1;\n \n-\tif (warn_ambiguous_refs && refs_found > 1)\n+\tif (warn_ambiguous_refs &&\n+\t    (refs_found > 1 ||\n+\t     !get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))\n \t\twarning(warn_msg, len, str);\n \n \tif (reflog_len) {\ndiff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh\nindex 6b3d797..db22808 100755\n--- a/t/t1512-rev-parse-disambiguation.sh\n+++ b/t/t1512-rev-parse-disambiguation.sh\n@@ -261,4 +261,22 @@ test_expect_success 'rev-parse --disambiguate' '\n \ttest \"$(sed -e \"s/^\\(.........\\).*/\\1/\" actual | sort -u)\" = 000000000\n '\n \n+test_expect_success 'ambiguous 40-hex ref' '\n+\tTREE=$(git mktree </dev/null) &&\n+\tREF=`git rev-parse HEAD` &&\n+\tVAL=$(git commit-tree $TREE </dev/null) &&\n+\tgit update-ref refs/heads/$REF $VAL &&\n+\ttest `git rev-parse $REF 2>err` = $REF &&\n+\tgrep \"refname.*${REF}.*ambiguous\" err\n+'\n+\n+test_expect_success 'ambiguous short sha1 ref' '\n+\tTREE=$(git mktree </dev/null) &&\n+\tREF=`git rev-parse --short HEAD` &&\n+\tVAL=$(git commit-tree $TREE </dev/null) &&\n+\tgit update-ref refs/heads/$REF $VAL &&\n+\ttest `git rev-parse $REF 2>err` = $VAL &&\n+\tgrep \"refname.*${REF}.*ambiguous\" err\n+'\n+\n test_done\n-- \n1.8.2.83.gc99314b\n"},{"id":"216626","messageId":"7v38tylqkp.fsf@alter.siamese.dyndns.org","threadId":"33690","inReplyTo":"1367639113-17342-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH] get_sha1: improve ambiguity warning regarding SHA-1 and ref names","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-07T16:09:26Z","receivedAt":"2013-05-07T16:09:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n>  > That's an important feature for safety. When a script has created an\n>  > object or learned about it some other way, as long as it doesn't\n>  > abbreviate its name it can be sure that git commands will not\n>  > misunderstand it.\n>  >\n>  > So I think this is a bad change.\n> ...\n>  static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n>  {\n>  \tstatic const char *warn_msg = \"refname '%.*s' is ambiguous.\";\n> +\tunsigned char tmp_sha1[20];\n>  \tchar *real_ref = NULL;\n>  \tint refs_found = 0;\n>  \tint at, reflog_len;\n>  \n> -\tif (len == 40 && !get_sha1_hex(str, sha1))\n> +\tif (len == 40 && !get_sha1_hex(str, sha1)) {\n> +\t\trefs_found = dwim_ref(str, len, tmp_sha1, &real_ref);\n> +\t\tif (refs_found > 0 && warn_ambiguous_refs)\n> +\t\t\twarning(warn_msg, len, str);\n\nThe warning is issued at the right spot from the codeflow's point of\nview, but it is very likely that the user did not even mean to use\nthe str in question as a 'refname'. The warning message we see above\nis not appropriate for this case, is it?\n\n> +\t\tfree(real_ref);\n>  \t\treturn 0;\n> +\t}\n>  \n>  \t/* basic@{time or number or -number} format to query ref-log */\n>  \treflog_len = at = 0;\n> @@ -481,7 +487,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n>  \tif (!refs_found)\n>  \t\treturn -1;\n>  \n> -\tif (warn_ambiguous_refs && refs_found > 1)\n> +\tif (warn_ambiguous_refs &&\n> +\t    (refs_found > 1 ||\n> +\t     !get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))\n>  \t\twarning(warn_msg, len, str);\n\nDitto for the case in which (refs_found <= 1) and get_short_sha1()\nfinds str as a short object name.\n\n\n> diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh\n> index 6b3d797..db22808 100755\n> --- a/t/t1512-rev-parse-disambiguation.sh\n> +++ b/t/t1512-rev-parse-disambiguation.sh\n> @@ -261,4 +261,22 @@ test_expect_success 'rev-parse --disambiguate' '\n>  \ttest \"$(sed -e \"s/^\\(.........\\).*/\\1/\" actual | sort -u)\" = 000000000\n>  '\n>  \n> +test_expect_success 'ambiguous 40-hex ref' '\n> +\tTREE=$(git mktree </dev/null) &&\n> +\tREF=`git rev-parse HEAD` &&\n> +\tVAL=$(git commit-tree $TREE </dev/null) &&\n> +\tgit update-ref refs/heads/$REF $VAL &&\n> +\ttest `git rev-parse $REF 2>err` = $REF &&\n> +\tgrep \"refname.*${REF}.*ambiguous\" err\n> +'\n> +\n> +test_expect_success 'ambiguous short sha1 ref' '\n> +\tTREE=$(git mktree </dev/null) &&\n> +\tREF=`git rev-parse --short HEAD` &&\n> +\tVAL=$(git commit-tree $TREE </dev/null) &&\n> +\tgit update-ref refs/heads/$REF $VAL &&\n> +\ttest `git rev-parse $REF 2>err` = $VAL &&\n> +\tgrep \"refname.*${REF}.*ambiguous\" err\n> +'\n> +\n>  test_done\n"},{"id":"218810","messageId":"1369829562-21835-1-git-send-email-pclouds@gmail.com","threadId":"33690","inReplyTo":"1367639113-17342-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2] get_sha1: warn about full or short object names that look like refs","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2013-05-29T12:12:42Z","receivedAt":"2013-05-29T12:12:42Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"When we get 40 hex digits, we immediately assume it's an SHA-1. This\nis the right thing to do because we have no way else to specify an\nobject. If there is a ref with the same object name, it will be\nignored. Warn the user about this case because the ref with full\nobject name is likely a mistake, for example\n\n    git checkout -b $empty_var $(git rev-parse something)\n\nadvice.object_name_warning is not documented because frankly people\nshould not be aware about it until they encounter this situation.\n\nWhile at there, warn about ambiguation with abbreviated SHA-1 too.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n advice.c                            |  2 ++\n advice.h                            |  1 +\n sha1_name.c                         | 25 +++++++++++++++++++++++--\n t/t1512-rev-parse-disambiguation.sh | 18 ++++++++++++++++++\n 4 files changed, 44 insertions(+), 2 deletions(-)\n\ndiff --git a/advice.c b/advice.c\nindex 780f58d..22abde9 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -12,6 +12,7 @@ int advice_commit_before_merge = 1;\n int advice_resolve_conflict = 1;\n int advice_implicit_identity = 1;\n int advice_detached_head = 1;\n+int advice_object_name_warning = 1;\n \n static struct {\n \tconst char *name;\n@@ -29,6 +30,7 @@ static struct {\n \t{ \"resolveconflict\", &advice_resolve_conflict },\n \t{ \"implicitidentity\", &advice_implicit_identity },\n \t{ \"detachedhead\", &advice_detached_head },\n+\t{ \"object_name_warning\", &advice_object_name_warning },\n \n \t/* make this an alias for backward compatibility */\n \t{ \"pushnonfastforward\", &advice_push_update_rejected }\ndiff --git a/advice.h b/advice.h\nindex fad36df..24d5420 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -15,6 +15,7 @@ extern int advice_commit_before_merge;\n extern int advice_resolve_conflict;\n extern int advice_implicit_identity;\n extern int advice_detached_head;\n+extern int advice_object_name_warning;\n \n int git_default_advice_config(const char *var, const char *value);\n void advise(const char *advice, ...);\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 95003c7..502d107 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -435,12 +435,31 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l\n static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n {\n \tstatic const char *warn_msg = \"refname '%.*s' is ambiguous.\";\n+\tstatic const char *object_name_msg = N_(\n+\t\"Git normally never creates a ref that ends with 40 hex characters\\n\"\n+\t\"because it will be ignored when you just specify 40-hex. These refs\\n\"\n+\t\"may be created by mistake. For example,\\n\"\n+\t\"\\n\"\n+\t\"  git checkout -b $br $(git rev-parse ...)\\n\"\n+\t\"\\n\"\n+\t\"where \\\"$br\\\" is somehow empty and a 40-hex ref is created. Please\\n\"\n+\t\"examine these refs and maybe delete them. Turn this message off by\\n\"\n+\t\"running \\\"git config advice.object_name_warning false\\\"\");\n+\tunsigned char tmp_sha1[20];\n \tchar *real_ref = NULL;\n \tint refs_found = 0;\n \tint at, reflog_len;\n \n-\tif (len == 40 && !get_sha1_hex(str, sha1))\n+\tif (len == 40 && !get_sha1_hex(str, sha1)) {\n+\t\trefs_found = dwim_ref(str, len, tmp_sha1, &real_ref);\n+\t\tif (refs_found > 0 && warn_ambiguous_refs) {\n+\t\t\twarning(warn_msg, len, str);\n+\t\t\tif (advice_object_name_warning)\n+\t\t\t\tfprintf(stderr, \"%s\\n\", _(object_name_msg));\n+\t\t}\n+\t\tfree(real_ref);\n \t\treturn 0;\n+\t}\n \n \t/* basic@{time or number or -number} format to query ref-log */\n \treflog_len = at = 0;\n@@ -481,7 +500,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n \tif (!refs_found)\n \t\treturn -1;\n \n-\tif (warn_ambiguous_refs && refs_found > 1)\n+\tif (warn_ambiguous_refs &&\n+\t    (refs_found > 1 ||\n+\t     !get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))\n \t\twarning(warn_msg, len, str);\n \n \tif (reflog_len) {\ndiff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh\nindex 6b3d797..db22808 100755\n--- a/t/t1512-rev-parse-disambiguation.sh\n+++ b/t/t1512-rev-parse-disambiguation.sh\n@@ -261,4 +261,22 @@ test_expect_success 'rev-parse --disambiguate' '\n \ttest \"$(sed -e \"s/^\\(.........\\).*/\\1/\" actual | sort -u)\" = 000000000\n '\n \n+test_expect_success 'ambiguous 40-hex ref' '\n+\tTREE=$(git mktree </dev/null) &&\n+\tREF=`git rev-parse HEAD` &&\n+\tVAL=$(git commit-tree $TREE </dev/null) &&\n+\tgit update-ref refs/heads/$REF $VAL &&\n+\ttest `git rev-parse $REF 2>err` = $REF &&\n+\tgrep \"refname.*${REF}.*ambiguous\" err\n+'\n+\n+test_expect_success 'ambiguous short sha1 ref' '\n+\tTREE=$(git mktree </dev/null) &&\n+\tREF=`git rev-parse --short HEAD` &&\n+\tVAL=$(git commit-tree $TREE </dev/null) &&\n+\tgit update-ref refs/heads/$REF $VAL &&\n+\ttest `git rev-parse $REF 2>err` = $VAL &&\n+\tgrep \"refname.*${REF}.*ambiguous\" err\n+'\n+\n test_done\n-- \n1.8.2.83.gc99314b\n"}]}