{"thread":{"id":"41564","subject":"git cat-file -e behavior","startedAt":"2016-02-29T09:58:29Z","lastAt":"2016-02-29T12:40:32Z","messageCount":5,"participants":["Michal Čihař","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"279760","messageId":"56D41645.4050800@cihar.com","threadId":"41564","inReplyTo":null,"subject":"git cat-file -e behavior","fromName":"Michal Čihař","fromEmail":"michal@cihar.com","sentAt":"2016-02-29T09:58:29Z","receivedAt":"2016-02-29T09:58:29Z","isPatch":false,"sender":{"key":"michal@cihar.com","avatar":"https://gravatar.com/avatar/6e190a9cbe96f1cc30a1014ac9a626d63fcc25d1d2328188e722c6c90e078303?d=mp&s=160"},"body":"Hi\n\nthe documentation for \"git cat-file -e\" says:\n\n> Suppress all output; instead exit with zero status if <object> exists\nand is a valid object.\n\nHowever running it on non existing object will complain \"fatal: Not a\nvalid object name\".\n\n$ git cat-file -e master:README.rst\n$ echo $?\n0\n$ git cat-file -e master:foo\nfatal: Not a valid object name master:foo\n$ echo $?\n128\n\nIs the output in this case expected?\n\nI'm currently running 2.7.0.\n\n-- \n\tMichal Čihař | http://cihar.com | http://blog.cihar.com\n\n"},{"id":"279769","messageId":"20160229114455.GD29769@sigill.intra.peff.net","threadId":"41564","inReplyTo":"56D41645.4050800@cihar.com","subject":"Re: git cat-file -e behavior","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-29T11:44:55Z","receivedAt":"2016-02-29T11:44:55Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 29, 2016 at 10:58:29AM +0100, Michal Čihař wrote:\n\n> the documentation for \"git cat-file -e\" says:\n> \n> > Suppress all output; instead exit with zero status if <object> exists\n> and is a valid object.\n> \n> However running it on non existing object will complain \"fatal: Not a\n> valid object name\".\n> \n> $ git cat-file -e master:README.rst\n> $ echo $?\n> 0\n> $ git cat-file -e master:foo\n> fatal: Not a valid object name master:foo\n> $ echo $?\n> 128\n> \n> Is the output in this case expected?\n> \n> I'm currently running 2.7.0.\n\nIt looks like it has been this way forever. The first thing we do with\nthe object is resolve its name to a sha1, and that's where the error you\nsee comes from. And then we actually check whether we have the object.\n\nI think the intended use was to feed it a sha1 to see if it exists. Then\nthe name-resolution step is a noop.\n\nI'm not sure if the behavior you are seeing is all that bad (the\ndocumentation could be read as suppressing the normal stdout output, but\nerror messages remain), but it would be easy to change:\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 54db118..afde169 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -35,6 +35,9 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n \tif (unknown_type)\n \t\tflags |= LOOKUP_UNKNOWN_OBJECT;\n \n+\tif (opt == 'e')\n+\t\treturn !has_sha1_file(sha1);\n+\n \tif (get_sha1_with_context(obj_name, 0, sha1, &obj_context))\n \t\tdie(\"Not a valid object name %s\", obj_name);\n \n@@ -58,9 +61,6 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n \t\tprintf(\"%lu\\n\", size);\n \t\treturn 0;\n \n-\tcase 'e':\n-\t\treturn !has_sha1_file(sha1);\n-\n \tcase 'c':\n \t\tif (!obj_context.path[0])\n \t\t\tdie(\"git cat-file --textconv %s: <object> must be <sha1:path>\",\n"},{"id":"279771","messageId":"56D436A2.4090202@cihar.com","threadId":"41564","inReplyTo":"20160229114455.GD29769@sigill.intra.peff.net","subject":"Re: git cat-file -e behavior","fromName":"Michal Čihař","fromEmail":"michal@cihar.com","sentAt":"2016-02-29T12:16:34Z","receivedAt":"2016-02-29T12:16:34Z","isPatch":false,"sender":{"key":"michal@cihar.com","avatar":"https://gravatar.com/avatar/6e190a9cbe96f1cc30a1014ac9a626d63fcc25d1d2328188e722c6c90e078303?d=mp&s=160"},"body":"Hi\n\nDne 29.2.2016 v 12:44 Jeff King napsal(a):\n> It looks like it has been this way forever. The first thing we do with\n> the object is resolve its name to a sha1, and that's where the error you\n> see comes from. And then we actually check whether we have the object.\n> \n> I think the intended use was to feed it a sha1 to see if it exists. Then\n> the name-resolution step is a noop.\n\nI found this as best way to check whether file exists in branch.\nChecking git ls-tree output seems less error prone than checking return\nvalue of git cat-file -e...\n\n> I'm not sure if the behavior you are seeing is all that bad (the\n> documentation could be read as suppressing the normal stdout output, but\n> error messages remain), \n\nI understand this, that's why I'm asking whether it's expected output or\nnot :-).\n\n-- \n\tMichal Čihař | http://cihar.com | http://blog.cihar.com\n\n"},{"id":"279773","messageId":"20160229123645.GA20754@sigill.intra.peff.net","threadId":"41564","inReplyTo":"56D436A2.4090202@cihar.com","subject":"Re: git cat-file -e behavior","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-29T12:36:45Z","receivedAt":"2016-02-29T12:36:45Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 29, 2016 at 01:16:34PM +0100, Michal Čihař wrote:\n\n> Dne 29.2.2016 v 12:44 Jeff King napsal(a):\n> > It looks like it has been this way forever. The first thing we do with\n> > the object is resolve its name to a sha1, and that's where the error you\n> > see comes from. And then we actually check whether we have the object.\n> > \n> > I think the intended use was to feed it a sha1 to see if it exists. Then\n> > the name-resolution step is a noop.\n> \n> I found this as best way to check whether file exists in branch.\n> Checking git ls-tree output seems less error prone than checking return\n> value of git cat-file -e...\n\nI think the usual way to do that would be:\n\n  git rev-parse --verify $branch:$path >/dev/null\n\nwhich just resolves the name (not that what you are doing is wrong, I\njust think rev-parse is the way we usually do it in our scripts).\n\nThat _will_ write a message to stderr when the name doesn't resolve.\n\n-Peff\n"},{"id":"279774","messageId":"20160229124032.GA21158@sigill.intra.peff.net","threadId":"41564","inReplyTo":"20160229114455.GD29769@sigill.intra.peff.net","subject":"Re: git cat-file -e behavior","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-29T12:40:32Z","receivedAt":"2016-02-29T12:40:32Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 29, 2016 at 06:44:55AM -0500, Jeff King wrote:\n\n> [...]but it would be easy to change:\n> \n> diff --git a/builtin/cat-file.c b/builtin/cat-file.c\n> index 54db118..afde169 100644\n> --- a/builtin/cat-file.c\n> +++ b/builtin/cat-file.c\n> @@ -35,6 +35,9 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n>  \tif (unknown_type)\n>  \t\tflags |= LOOKUP_UNKNOWN_OBJECT;\n>  \n> +\tif (opt == 'e')\n> +\t\treturn !has_sha1_file(sha1);\n> +\n>  \tif (get_sha1_with_context(obj_name, 0, sha1, &obj_context))\n>  \t\tdie(\"Not a valid object name %s\", obj_name);\n>  \n> @@ -58,9 +61,6 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n>  \t\tprintf(\"%lu\\n\", size);\n>  \t\treturn 0;\n>  \n> -\tcase 'e':\n> -\t\treturn !has_sha1_file(sha1);\n> -\n>  \tcase 'c':\n>  \t\tif (!obj_context.path[0])\n>  \t\t\tdie(\"git cat-file --textconv %s: <object> must be <sha1:path>\",\n\nThis is wrong, of course. We still need to call get_sha1, but just need\nto not die. So it's more like this (totally untested, naturally):\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 54db118..44add8c 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -35,8 +35,11 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n \tif (unknown_type)\n \t\tflags |= LOOKUP_UNKNOWN_OBJECT;\n \n-\tif (get_sha1_with_context(obj_name, 0, sha1, &obj_context))\n+\tif (get_sha1_with_context(obj_name, 0, sha1, &obj_context)) {\n+\t\tif (opt == 'e')\n+\t\t\treturn 1;\n \t\tdie(\"Not a valid object name %s\", obj_name);\n+\t}\n \n \tbuf = NULL;\n \tswitch (opt) {\n\n-Peff\n"}]}