{"thread":{"id":"57137","subject":"bug: git name-rev --stdin --no-undefined on detached head","startedAt":"2021-12-22T10:06:22Z","lastAt":"2021-12-31T17:16:46Z","messageCount":8,"participants":["Erik Cervin Edin","John Cai","Junio C Hamano","Philip Oakley"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"444757","messageId":"CA+JQ7M-ORVCj6teGjVy01SF=f0=PdKKYdHNU9ruK9XUAX9F8Ag@mail.gmail.com","threadId":"57137","inReplyTo":null,"subject":"bug: git name-rev --stdin --no-undefined on detached head","fromName":"Erik Cervin Edin","fromEmail":"erik@cervined.in","sentAt":"2021-12-22T10:05:45Z","receivedAt":"2021-12-22T10:06:22Z","isPatch":false,"sender":{"key":"erik@cervined.in","avatar":null},"body":"Hey all!\n\nI ran into a situation that I think may be a bug\nusing git name-rev for detached heads.\n\nSteps to reproduce:\nCreate a detached head\n  git checkout --detached\n  git commit --allow-empty -m foo\n\nExpected results:\nMy understanding is that\n  git name-rev $(git rev-list -1 HEAD)\n  git rev-list -1 HEAD | git name-rev --stdin\nshould yield the same result.\n\nAs well as combining with other flags\nlike --name-only / --no-undefined\n\nActual results:\nWhere this fails as expected\n  git name-rev --no-undefined $(git rev-list HEAD)\nthis just prints the SHA wo failing\n  git rev-list -1 HEAD |  git name-rev --stdin --no-undefined\n\n\"name-only\" is also affected\n  git rev-list -1 HEAD |  git name-rev --stdin --name-only\nreturns the SHA and not the name\n\nTested on\ngit version 2.34.1.windows.1\n-- \nErik Cervin-Edin\n"},{"id":"444872","messageId":"DA9B4728-C45D-4CA0-A40D-4A81665AB0E6@gitlab.com","threadId":"57137","inReplyTo":"CA+JQ7M-ORVCj6teGjVy01SF=f0=PdKKYdHNU9ruK9XUAX9F8Ag@mail.gmail.com","subject":"Re: bug: git name-rev --stdin --no-undefined on detached head","fromName":"John Cai","fromEmail":"jcai@gitlab.com","sentAt":"2021-12-23T18:39:23Z","receivedAt":"2021-12-23T18:39:27Z","isPatch":false,"sender":{"key":"jcai@gitlab.com","avatar":"https://gravatar.com/avatar/4ba958d432b21b53dd76009b44d31b70bd387a31d2957cee1b257ced4bf812f8?d=mp&s=160"},"body":"It seems like this bug can be generalized to “git name-rev --stdin” does not work with --no-undefined nor --name-only\n\nThe --name-only case seems clear to me that we should fix it. It’s misleading to return the sha instead of “undefined” for a rev without a symbolic name, as a sha could be a symbolic name.\n\nI think we can also make the argument that --no-undefined should also die in --stdin mode when given a rev without any symbolic names.\n\n\n> On Dec 22, 2021, at 2:05 AM, Erik Cervin Edin <erik@cervined.in> wrote:\n> \n> Hey all!\n> \n> I ran into a situation that I think may be a bug\n> using git name-rev for detached heads.\n> \n> Steps to reproduce:\n> Create a detached head\n>  git checkout --detached\n>  git commit --allow-empty -m foo\n> \n> Expected results:\n> My understanding is that\n>  git name-rev $(git rev-list -1 HEAD)\n>  git rev-list -1 HEAD | git name-rev --stdin\n> should yield the same result.\n> \n> As well as combining with other flags\n> like --name-only / --no-undefined\n> \n> Actual results:\n> Where this fails as expected\n>  git name-rev --no-undefined $(git rev-list HEAD)\n> this just prints the SHA wo failing\n>  git rev-list -1 HEAD |  git name-rev --stdin --no-undefined\n> \n> \"name-only\" is also affected\n>  git rev-list -1 HEAD |  git name-rev --stdin --name-only\n> returns the SHA and not the name\n> \n> Tested on\n> git version 2.34.1.windows.1\n> -- \n> Erik Cervin-Edin\n\n"},{"id":"444899","messageId":"D22DF4C4-C98C-45FB-8D26-57B50A44FA3F@gmail.com","threadId":"57137","inReplyTo":"DA9B4728-C45D-4CA0-A40D-4A81665AB0E6@gitlab.com","subject":"Re: bug: git name-rev --stdin --no-undefined on detached head","fromName":"John Cai","fromEmail":"johncai86@gmail.com","sentAt":"2021-12-24T06:09:50Z","receivedAt":"2021-12-24T06:09:53Z","isPatch":false,"sender":{"key":"johncai86@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2354211?v=4"},"body":"\n> On Dec 23, 2021, at 10:39 AM, John Cai <jcai@gitlab.com> wrote:\n> \n> It seems like this bug can be generalized to “git name-rev --stdin” does not work with --no-undefined nor --name-only\n> \n> The --name-only case seems clear to me that we should fix it. It’s misleading to return the sha instead of “undefined” for a rev without a symbolic name, as a sha could be a symbolic name.\n> \n> I think we can also make the argument that --no-undefined should also die in --stdin mode when given a rev without any symbolic names.\n\nWhile I think this would make name-rev more consistent, I’d be interested in hearing what others think about changing the behavior of this command. This would have the potential of breaking scripts that rely on the current behavior. Since I’m a bit new, I’m wondering how we generally handle these cases?\n\n> \n> \n>> On Dec 22, 2021, at 2:05 AM, Erik Cervin Edin <erik@cervined.in> wrote:\n>> \n>> Hey all!\n>> \n>> I ran into a situation that I think may be a bug\n>> using git name-rev for detached heads.\n>> \n>> Steps to reproduce:\n>> Create a detached head\n>> git checkout --detached\n>> git commit --allow-empty -m foo\n>> \n>> Expected results:\n>> My understanding is that\n>> git name-rev $(git rev-list -1 HEAD)\n>> git rev-list -1 HEAD | git name-rev --stdin\n>> should yield the same result.\n>> \n>> As well as combining with other flags\n>> like --name-only / --no-undefined\n>> \n>> Actual results:\n>> Where this fails as expected\n>> git name-rev --no-undefined $(git rev-list HEAD)\n>> this just prints the SHA wo failing\n>> git rev-list -1 HEAD |  git name-rev --stdin --no-undefined\n>> \n>> \"name-only\" is also affected\n>> git rev-list -1 HEAD |  git name-rev --stdin --name-only\n>> returns the SHA and not the name\n>> \n>> Tested on\n>> git version 2.34.1.windows.1\n>> -- \n>> Erik Cervin-Edin\n> \n\n"},{"id":"444903","messageId":"CA+JQ7M9xEHezQG0ui+jrhdWRHAausqxe5W7ucj4XkiLwnFL+Yw@mail.gmail.com","threadId":"57137","inReplyTo":"D22DF4C4-C98C-45FB-8D26-57B50A44FA3F@gmail.com","subject":"Re: bug: git name-rev --stdin --no-undefined on detached head","fromName":"Erik Cervin Edin","fromEmail":"erik@cervined.in","sentAt":"2021-12-24T11:44:49Z","receivedAt":"2021-12-24T11:45:29Z","isPatch":false,"sender":{"key":"erik@cervined.in","avatar":null},"body":"> On Fri, Dec 24, 2021 at 7:09 AM John Cai <johncai86@gmail.com> wrote:\n> This would have the potential of breaking scripts that rely on the current behavior.\n\nPresumably, using --no-undefined scripts rely on presumed behavior\nthat doesn't exist.\nSimilarly, using --name-only should expect to return a symbolic name\nWhile it's possible, I think it's rare that this would break scripts\nin an unacceptable way.\n\n> On Fri, Dec 24, 2021 at 7:09 AM John Cai <johncai86@gmail.com> wrote:\n> Since I’m a bit new, I’m wondering how we generally handle these cases?\n\nI'm also new so I can't really comment on this :)\nThough I believe the git suite in general is quite adamant on\nbackwards compatibility\n"},{"id":"444926","messageId":"xmqqk0ft3i3g.fsf@gitster.g","threadId":"57137","inReplyTo":"DA9B4728-C45D-4CA0-A40D-4A81665AB0E6@gitlab.com","subject":"Re: bug: git name-rev --stdin --no-undefined on detached head","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-12-24T19:42:27Z","receivedAt":"2021-12-24T19:44:32Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Cai <jcai@gitlab.com> writes:\n\n> It seems like this bug can be generalized to “git name-rev\n> --stdin” does not work with --no-undefined nor --name-only\n>\n> The --name-only case seems clear to me that we should fix\n> it. It’s misleading to return the sha instead of “undefined”\n> for a rev without a symbolic name, as a sha could be a symbolic\n> name.\n>\n> I think we can also make the argument that --no-undefined should\n> also die in --stdin mode when given a rev without any symbolic\n> names.\n\nHmph, the manual page documents:\n\n    --stdin::\n            Transform stdin by substituting all the 40-character SHA-1\n            hexes (say $hex) with \"$hex ($rev_name)\".  When used with\n            --name-only, substitute with \"$rev_name\", omitting $hex\n            altogether.  Intended for the scripter's use.\n\nIt is unfortunate that the way this option works is confusingly a\nbit different from what we learned to expect from the --stdin option\nother subcommands like \"git pack-objects --stdin\" takes.  In short,\nthese are not equivalent:\n\n\tgit name-rev [<options>] $string\n        printf \"%s\" \"$string\" | xargs git name-rev [<options>]\n        printf \"%s\" \"$string\" | git name-rev --stdin [<options>]\n\nThe first two are supposed to be the equivalent, but the third one\nis different by design.  Its `--stdin` mode is expected to read\nsomething like this [*]:\n\n\t$ cat sample.txt\n        A revision that exists 2ae0a9cb82 is shown here,\n        and its full name is 2ae0a9cb8298185a94e5998086f380a355dd8907\n        while its tree object is 70d105cc79e63b81cfdcb08a15297c23e60b07ad\n        which probably is undescribable hexdigits.\n\nand its designed use is to annotate its input into a more reader\nfriendly from with refnames where possible.  Here is what we get:\n\n        $ git name-rev --stdin <sample.txt\n        A revision that exists 2ae0a9cb82 is shown here,\n        and its full name is 2ae0a9cb8298185a94e5998086f380a355dd8907 (master)\n        while its tree object is 70d105cc79e63b81cfdcb08a15297c23e60b07ad\n        which probably is undescribable hexdigits.\n\nI notice a few things.\n\n * An abbreviated commit object name is not affected;\n\n * A 40-digit string that cannot be described with a reference is\n   left alone, without \"undefined\".\n\nIt might be debatable that the latter may want to be annotated with\n\"undefined\", but as the command does not molest other noise strings\nlike \"its\" \"full\" name\" in the input, I think the current behaviour\nis preferred over appending \"(undefined)\" after a string we do not\nrecognize that happens to be 40-hex.\n\nWhen used with --name-only, we see this:\n\n\t$ git name-rev --name-only --stdin <sample.txt\n        A revision that exists 2ae0a9cb82 is shown here,\n        and its full name is master\n        while its tree object is 70d105cc79e63b81cfdcb08a15297c23e60b07ad\n        which probably is undescribable hexdigits.\n\nSo, as far as I can see, it is working as described.  If there is\nany bug in the things I saw and shown here, it is that it is\nmisleading to claim that this behaviour is intended for scripter's\nuse.  It clearly is not scripter friendly when you want to run\n\"name-rev\" on unbounded number of object names you have, which may\nnot fit on the command line, as that is not how it was designed to\nbe used.\n\nTwo possible things we can do to improve are\n\n * Fix the documentation; it is not for scripters but for annotating\n   text with object names.\n\n * Possibly add --names-from-standard-input option that would behave\n   more like \"we cannot afford to stuff all object names on the\n   command line, so we feed them one by one from the standard input\"\n   mode the \"--stdin\" option of other subcommands use.\n\nI do not think the latter is so important, as it is perfectly OK to\nuse xargs to split the large input into multiple invocations of\nname-rev.  This is unlike \"pack-objects --stdin\" where the command\nneeds to see _all_ input in a single invocation.\n\n\n[Footnote]\n\n* The sample input was produced with\n\n        $ cat >sample.txt <<EOF\n        A revision that exists $(git rev-parse --short HEAD) is shown here,\n        and its full name is $(git rev-parse HEAD)\n        while its tree object is $(git rev-parse HEAD:)\n        which probably is undescribable hexdigits.\n        EOF\n\nif you want to try it at home ;-)\n"},{"id":"444927","messageId":"E45DFA88-3D4D-46DD-9706-C090536CA702@gitlab.com","threadId":"57137","inReplyTo":"xmqqk0ft3i3g.fsf@gitster.g","subject":"Re: bug: git name-rev --stdin --no-undefined on detached head","fromName":"John Cai","fromEmail":"jcai@gitlab.com","sentAt":"2021-12-24T20:09:46Z","receivedAt":"2021-12-24T20:09:52Z","isPatch":false,"sender":{"key":"jcai@gitlab.com","avatar":"https://gravatar.com/avatar/4ba958d432b21b53dd76009b44d31b70bd387a31d2957cee1b257ced4bf812f8?d=mp&s=160"},"body":"\n\n> On Dec 24, 2021, at 11:42 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> \n> John Cai <jcai@gitlab.com> writes:\n> \n>> It seems like this bug can be generalized to “git name-rev\n>> --stdin” does not work with --no-undefined nor --name-only\n>> \n>> The --name-only case seems clear to me that we should fix\n>> it. It’s misleading to return the sha instead of “undefined”\n>> for a rev without a symbolic name, as a sha could be a symbolic\n>> name.\n>> \n>> I think we can also make the argument that --no-undefined should\n>> also die in --stdin mode when given a rev without any symbolic\n>> names.\n> \n> Hmph, the manual page documents:\n> \n>    --stdin::\n>            Transform stdin by substituting all the 40-character SHA-1\n>            hexes (say $hex) with \"$hex ($rev_name)\".  When used with\n>            --name-only, substitute with \"$rev_name\", omitting $hex\n>            altogether.  Intended for the scripter's use.\n> \n> It is unfortunate that the way this option works is confusingly a\n> bit different from what we learned to expect from the --stdin option\n> other subcommands like \"git pack-objects --stdin\" takes.  In short,\n> these are not equivalent:\n> \n> \tgit name-rev [<options>] $string\n>        printf \"%s\" \"$string\" | xargs git name-rev [<options>]\n>        printf \"%s\" \"$string\" | git name-rev --stdin [<options>]\n> \n> The first two are supposed to be the equivalent, but the third one\n> is different by design.  Its `--stdin` mode is expected to read\n> something like this [*]:\n> \n> \t$ cat sample.txt\n>        A revision that exists 2ae0a9cb82 is shown here,\n>        and its full name is 2ae0a9cb8298185a94e5998086f380a355dd8907\n>        while its tree object is 70d105cc79e63b81cfdcb08a15297c23e60b07ad\n>        which probably is undescribable hexdigits.\n> \n> and its designed use is to annotate its input into a more reader\n> friendly from with refnames where possible.  \n\nNo wonder! This elucidates why I found the user experience of the --stdin \nmode a bit unexpected, as it would simply echo back the input when it couldn’t find a \nvalid object or refname rather than return an error message. I think I totally missed \nthe verbiage in the documentation that states its meant to **substitute** text in stdin.\nMakes sense to echo back the input if nothing useful could be found.\n\n> Here is what we get:\n> \n>        $ git name-rev --stdin <sample.txt\n>        A revision that exists 2ae0a9cb82 is shown here,\n>        and its full name is 2ae0a9cb8298185a94e5998086f380a355dd8907 (master)\n>        while its tree object is 70d105cc79e63b81cfdcb08a15297c23e60b07ad\n>        which probably is undescribable hexdigits.\n> \n> I notice a few things.\n> \n> * An abbreviated commit object name is not affected;\n> \n> * A 40-digit string that cannot be described with a reference is\n>   left alone, without \"undefined\".\n> \n> It might be debatable that the latter may want to be annotated with\n> \"undefined\", but as the command does not molest other noise strings\n> like \"its\" \"full\" name\" in the input, I think the current behaviour\n> is preferred over appending \"(undefined)\" after a string we do not\n> recognize that happens to be 40-hex.\n> \n> When used with --name-only, we see this:\n> \n> \t$ git name-rev --name-only --stdin <sample.txt\n>        A revision that exists 2ae0a9cb82 is shown here,\n>        and its full name is master\n>        while its tree object is 70d105cc79e63b81cfdcb08a15297c23e60b07ad\n>        which probably is undescribable hexdigits.\n> \n> So, as far as I can see, it is working as described.  If there is\n> any bug in the things I saw and shown here, it is that it is\n> misleading to claim that this behaviour is intended for scripter's\n> use.  It clearly is not scripter friendly when you want to run\n> \"name-rev\" on unbounded number of object names you have, which may\n> not fit on the command line, as that is not how it was designed to\n> be used.\n> \n> Two possible things we can do to improve are\n> \n> * Fix the documentation; it is not for scripters but for annotating\n>   text with object names.\n\nMakes sense to update the documentation to make it clear what --stdin mode is\nmeant to do. \n\n> \n> * Possibly add --names-from-standard-input option that would behave\n>   more like \"we cannot afford to stuff all object names on the\n>   command line, so we feed them one by one from the standard input\"\n>   mode the \"--stdin\" option of other subcommands use.\n> \n> I do not think the latter is so important, as it is perfectly OK to\n> use xargs to split the large input into multiple invocations of\n> name-rev.  This is unlike \"pack-objects --stdin\" where the command\n> needs to see _all_ input in a single invocation.\n> \n> \n> [Footnote]\n> \n> * The sample input was produced with\n> \n>        $ cat >sample.txt <<EOF\n>        A revision that exists $(git rev-parse --short HEAD) is shown here,\n>        and its full name is $(git rev-parse HEAD)\n>        while its tree object is $(git rev-parse HEAD:)\n>        which probably is undescribable hexdigits.\n>        EOF\n> \n> if you want to try it at home ;-)\n\n"},{"id":"444930","messageId":"xmqqsfuh1pxz.fsf@gitster.g","threadId":"57137","inReplyTo":"xmqqk0ft3i3g.fsf@gitster.g","subject":"Re: bug: git name-rev --stdin --no-undefined on detached head","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-12-25T00:35:52Z","receivedAt":"2021-12-25T00:35:58Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Two possible things we can do to improve are\n>\n>  * Fix the documentation; it is not for scripters but for annotating\n>    text with object names.\n>\n>  * Possibly add --names-from-standard-input option that would behave\n>    more like \"we cannot afford to stuff all object names on the\n>    command line, so we feed them one by one from the standard input\"\n>    mode the \"--stdin\" option of other subcommands use.\n>\n> I do not think the latter is so important, as it is perfectly OK to\n> use xargs to split the large input into multiple invocations of\n> name-rev.  This is unlike \"pack-objects --stdin\" where the command\n> needs to see _all_ input in a single invocation.\n\nThis is primarily to teach newer developers how incompatible changes\nare done in this project.  I am not suggesting that introducing such\nan incompatible change and following through these steps to the end\nis a good idea in this case.\n\nHypothetically, if name-rev were so important a command that the\nxargs based workaround were unacceptable, what we would probably\ndo is to make the following changes over time.\n\n 1. Introduce a new `--annotate-text` option, which is a synonym to\n    the current `--stdin` option.  `--stdin` will work the same way\n    as today, but using it will issue a warning() to the standard\n    error to tell people to use the `--annotate-text` option\n    instead.\n\n 2. After a while, change `--stdin` to die() with a suggestion that\n    people should instead pipe into xargs to invoke name-rev\n    instead.\n\n 3. After the above two steps, users and scripts of `--stdin` will\n    go extinct.  Reintroduce `--stdin` but with a behaviour more in\n    line with the `--stdin` option of other subcommands, i.e. take\n    one arg per line from the standard input, and behave as if they\n    came in the argv[] array.\n\nThe idea is to give users an early warning that is annoying enough\nto encourage migration, ample time to adjust to the new world order,\nand to ensure that there are no stragglers that gets hurt when the\nname gets reused for an option with totally different behaviour.\n\nIt may not be a bad idea to do steps #1 and #2, though.  I do not\nthink xargs name-rev is bad enough to require going to the step #3,\nbut `--stdin` that exists and does a wrong thing is much worse than\n`--stdin` that does not exist, and finishing upto step #2 is enough\nto rectify that.\n"},{"id":"445291","messageId":"9b13b1d1-8e0f-b5c9-ad66-7a0e63eb0b13@iee.email","threadId":"57137","inReplyTo":"xmqqk0ft3i3g.fsf@gitster.g","subject":"Re: bug: git name-rev --stdin --no-undefined on detached head","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.email","sentAt":"2021-12-31T17:16:43Z","receivedAt":"2021-12-31T17:16:46Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"Thanks you for the example..\n\nOn 24/12/2021 19:42, Junio C Hamano wrote:\n> * The sample input was produced with\n>\n>         $ cat >sample.txt <<EOF\n>         A revision that exists $(git rev-parse --short HEAD) is shown here,\n>         and its full name is $(git rev-parse HEAD)\n>         while its tree object is $(git rev-parse HEAD:)\n>         which probably is undescribable hexdigits.\n>         EOF\n>\n> if you want to try it at home ;-)\n\nThe ` $(git rev-parse HEAD:) ` technique is serendipitous. \n\nI'd forgotten that was how to get the commit object's tree  for further\ninvestigation, as I'd need it for my `deadhead` query [1], as used\nregularly in the Git-for-Windows merging-rebase (see also [2]).\n\nPhilip\n[1]\nhttps://lore.kernel.org/git/be7ec330-2b2c-a01f-c7ca-e5e752493ee0@iee.email/\n[2]\nhttps://lore.kernel.org/git/nycvar.QRO.7.76.6.2112101528200.90@tvgsbejvaqbjf.bet/\n"}]}