{"thread":{"id":"25649","subject":"git rev-parse -q --verify $SHA doesn't always quiet errors","startedAt":"2010-11-04T22:54:10Z","lastAt":"2010-11-05T22:40:24Z","messageCount":2,"participants":["Kevin Ballard","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"155237","messageId":"4A1CAE91-E31C-46B5-A614-9634D8FC1FB1@sb.org","threadId":"25649","inReplyTo":null,"subject":"git rev-parse -q --verify $SHA doesn't always quiet errors","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-11-04T22:54:10Z","receivedAt":"2010-11-04T22:54:10Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"The -q flag to git rev-parse --verify is supposed to quiet all errors.\nHowever it doesn't appear to quiet the \"short SHA1 is ambiguous\" error.\n\n% cd Dev/git\n% git rev-parse -q --verify e51d\nerror: short SHA1 e51d is ambiguous.\n\nI took a quick look, and the error is being emitted deep within\nsha1_name.c, far outside of any access to the -q flag. I'm not sure how\nto go about fixing this. Does anyone have any ideas?\n\nAlternatively, is there a better way to tell if a given string can\nresolve into a full sha1 besides\n\n  git rev-parse -q --verify \"$word\" 2>/dev/null\n\n-Kevin Ballard\n"},{"id":"155274","messageId":"20101105224024.GD4457@burratino","threadId":"25649","inReplyTo":"4A1CAE91-E31C-46B5-A614-9634D8FC1FB1@sb.org","subject":"Re: git rev-parse -q --verify $SHA doesn't always quiet errors","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-05T22:40:24Z","receivedAt":"2010-11-05T22:40:24Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Kevin Ballard wrote:\n\n> % cd Dev/git\n> % git rev-parse -q --verify e51d\n> error: short SHA1 e51d is ambiguous.\n> \n> I took a quick look, and the error is being emitted deep within\n> sha1_name.c, far outside of any access to the -q flag.\n\nSomething to play with.  Sloppy, untested, but maybe it gives an idea\nof what's possible.\n\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex a5a1c86..13f099a 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -108,8 +108,17 @@ static void show_with_type(int type, const char *arg)\n \tshow(arg);\n }\n \n+static void die_no_single_rev(int quiet)\n+{\n+\tif (quiet)\n+\t\texit(1);\n+\telse\n+\t\tdie(\"Needed a single revision\");\n+}\n+\n /* Output a revision, only if filter allows it */\n-static void show_rev(int type, const unsigned char *sha1, const char *name)\n+static void show_rev(int type, const unsigned char *sha1, const char *name,\n+\t\t     int verify, int quiet)\n {\n \tif (!(filter & DO_REVS))\n \t\treturn;\n@@ -137,6 +146,8 @@ static void show_rev(int type, const unsigned char *sha1, const char *name)\n \t\t\t\tshow_with_type(type, full);\n \t\t\t\tbreak;\n \t\t\tdefault: /* ambiguous */\n+\t\t\t\tif (verify)\n+\t\t\t\t\tdie_no_single_rev(quiet);\n \t\t\t\terror(\"refname '%s' is ambiguous\", name);\n \t\t\t\tbreak;\n \t\t\t}\n@@ -171,7 +182,7 @@ static int show_default(void)\n \n \t\tdef = NULL;\n \t\tif (!get_sha1(s, sha1)) {\n-\t\t\tshow_rev(NORMAL, sha1, s);\n+\t\t\tshow_rev(NORMAL, sha1, s, 0, 0);\n \t\t\treturn 1;\n \t\t}\n \t}\n@@ -180,13 +191,13 @@ static int show_default(void)\n \n static int show_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n {\n-\tshow_rev(NORMAL, sha1, refname);\n+\tshow_rev(NORMAL, sha1, refname, 0, 0);\n \treturn 0;\n }\n \n static int anti_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n {\n-\tshow_rev(REVERSED, sha1, refname);\n+\tshow_rev(REVERSED, sha1, refname, 0, 0);\n \treturn 0;\n }\n \n@@ -234,8 +245,8 @@ static int try_difference(const char *arg)\n \tif (dotdot == arg)\n \t\tthis = \"HEAD\";\n \tif (!get_sha1(this, sha1) && !get_sha1(next, end)) {\n-\t\tshow_rev(NORMAL, end, next);\n-\t\tshow_rev(symmetric ? NORMAL : REVERSED, sha1, this);\n+\t\tshow_rev(NORMAL, end, next, 0, 0);\n+\t\tshow_rev(symmetric ? NORMAL : REVERSED, sha1, this, 0, 0);\n \t\tif (symmetric) {\n \t\t\tstruct commit_list *exclude;\n \t\t\tstruct commit *a, *b;\n@@ -245,7 +256,8 @@ static int try_difference(const char *arg)\n \t\t\twhile (exclude) {\n \t\t\t\tstruct commit_list *n = exclude->next;\n \t\t\t\tshow_rev(REVERSED,\n-\t\t\t\t\t exclude->item->object.sha1,NULL);\n+\t\t\t\t\t exclude->item->object.sha1,\n+\t\t\t\t\t NULL, 0, 0);\n \t\t\t\tfree(exclude);\n \t\t\t\texclude = n;\n \t\t\t}\n@@ -277,11 +289,11 @@ static int try_parent_shorthands(const char *arg)\n \t\treturn 0;\n \n \tif (!parents_only)\n-\t\tshow_rev(NORMAL, sha1, arg);\n+\t\tshow_rev(NORMAL, sha1, arg, 0, 0);\n \tcommit = lookup_commit_reference(sha1);\n \tfor (parents = commit->parents; parents; parents = parents->next)\n \t\tshow_rev(parents_only ? NORMAL : REVERSED,\n-\t\t\t\tparents->item->object.sha1, arg);\n+\t\t\t\tparents->item->object.sha1, arg, 0, 0);\n \n \treturn 1;\n }\n@@ -429,14 +441,6 @@ static int cmd_sq_quote(int argc, const char **argv)\n \treturn 0;\n }\n \n-static void die_no_single_rev(int quiet)\n-{\n-\tif (quiet)\n-\t\texit(1);\n-\telse\n-\t\tdie(\"Needed a single revision\");\n-}\n-\n static const char builtin_rev_parse_usage[] =\n \"git rev-parse --parseopt [options] -- [<args>...]\\n\"\n \"   or: git rev-parse --sq-quote [<arg>...]\\n\"\n@@ -707,12 +711,15 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\tname++;\n \t\t\ttype = REVERSED;\n \t\t}\n-\t\tif (!get_sha1(name, sha1)) {\n-\t\t\tif (verify)\n-\t\t\t\trevs_count++;\n-\t\t\telse\n-\t\t\t\tshow_rev(type, sha1, name);\n-\t\t\tcontinue;\n+\t\t{\n+\t\t\tstruct object_context dummy;\n+\t\t\tif (!get_sha1_with_context_2(name, sha1, &dummy, 1, NULL, quiet)) {\n+\t\t\t\tif (verify)\n+\t\t\t\t\trevs_count++;\n+\t\t\t\telse\n+\t\t\t\t\tshow_rev(type, sha1, name, 0, 0);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t}\n \t\tif (verify)\n \t\t\tdie_no_single_rev(quiet);\n@@ -723,7 +730,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t}\n \tif (verify) {\n \t\tif (revs_count == 1) {\n-\t\t\tshow_rev(type, sha1, name);\n+\t\t\tshow_rev(type, sha1, name, verify, quiet);\n \t\t\treturn 0;\n \t\t} else if (revs_count == 0 && show_default())\n \t\t\treturn 0;\ndiff --git a/cache.h b/cache.h\nindex 33decd9..2bef387 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -773,6 +773,7 @@ static inline int get_sha1_with_mode(const char *str, unsigned char *sha1, unsig\n \treturn get_sha1_with_mode_1(str, sha1, mode, 1, NULL);\n }\n extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int gently, const char *prefix);\n+extern int get_sha1_with_context_2(const char *name, unsigned char *sha1, struct object_context *orc, int gently, const char *prefix, int quietly);\n static inline int get_sha1_with_context(const char *str, unsigned char *sha1, struct object_context *orc)\n {\n \treturn get_sha1_with_context_1(str, sha1, orc, 1, NULL);\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 484081d..5cefb75 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -611,7 +611,7 @@ static int get_describe_name(const char *name, int len, unsigned char *sha1)\n \treturn -1;\n }\n \n-static int get_sha1_1(const char *name, int len, unsigned char *sha1)\n+static int get_sha1_2(const char *name, int len, unsigned char *sha1, int quietly)\n {\n \tint ret, has_suffix;\n \tconst char *cp;\n@@ -656,7 +656,12 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)\n \tif (!ret)\n \t\treturn 0;\n \n-\treturn get_short_sha1(name, len, sha1, 0);\n+\treturn get_short_sha1(name, len, sha1, quietly);\n+}\n+\n+static int get_sha1_1(const char *name, int len, unsigned char *sha1)\n+{\n+\treturn get_sha1_2(name, len, sha1, 0);\n }\n \n /*\n@@ -1046,9 +1051,9 @@ int get_sha1_with_mode_1(const char *name, unsigned char *sha1, unsigned *mode,\n \treturn ret;\n }\n \n-int get_sha1_with_context_1(const char *name, unsigned char *sha1,\n+int get_sha1_with_context_2(const char *name, unsigned char *sha1,\n \t\t\t    struct object_context *oc,\n-\t\t\t    int gently, const char *prefix)\n+\t\t\t    int gently, const char *prefix, int quietly)\n {\n \tint ret, bracket_depth;\n \tint namelen = strlen(name);\n@@ -1056,7 +1061,7 @@ int get_sha1_with_context_1(const char *name, unsigned char *sha1,\n \n \tmemset(oc, 0, sizeof(*oc));\n \toc->mode = S_IFINVALID;\n-\tret = get_sha1_1(name, namelen, sha1);\n+\tret = get_sha1_2(name, namelen, sha1, quietly);\n \tif (!ret)\n \t\treturn ret;\n \t/* sha1:path --> object name of path in ent sha1\n@@ -1141,3 +1146,10 @@ int get_sha1_with_context_1(const char *name, unsigned char *sha1,\n \t}\n \treturn ret;\n }\n+\n+int get_sha1_with_context_1(const char *name, unsigned char *sha1,\n+\t\t\t    struct object_context *oc,\n+\t\t\t    int gently, const char *prefix)\n+{\n+\treturn get_sha1_with_context_2(name, sha1, oc, gently, prefix, 0);\n+}\n"}]}