{"thread":{"id":"60056","subject":"[Question] git rev-parse verify for non-existent object","startedAt":"2023-08-02T07:52:45Z","lastAt":"2023-08-03T06:16:46Z","messageCount":5,"participants":["ZheNing Hu","Christian Couder","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"480093","messageId":"CAOLTT8RvAbmS1SwFja8_+NSBBoL0gTH1RgpSN5CYtDWZscMYZA@mail.gmail.com","threadId":"60056","inReplyTo":null,"subject":"[Question] git rev-parse verify for non-existent object","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-08-02T07:50:13Z","receivedAt":"2023-08-02T07:52:45Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"In my case, I often need to use \"git rev-parse --verify\" to verify\nif a revision exists in the repository, and this usually works:\n\ngit rev-parse --verify HEAD\nafa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n\ngit rev-parse --verify afa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\nafa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n\ngit rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nfatal: Needed a single revision\n\nHowever, when I started checking for a non-existent OID that happened\nto be exactly 40 characters long, something unexpected happened.\n \"git rev-parse --verify\" did not produce any error messages.\nI consider this to be a BUG.\n\ngit rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\nI understand that using \"git cat-file --batch-check=\"%(objectname)\"\nmay be a potential solution, but I currently do not want to do it because\nit would require significant changes and I am unsure if the behavior\nwould be consistent.\n\nThe simplest solution for me would be to fix \"git rev-parse --verify\".\nWhat do you all think?\n\n--\nZheNing Hu\n"},{"id":"480094","messageId":"CAP8UFD02tYrz+bxoR_GQfYuxxrmv5=BXjcZuiqXbX3m7N2dPaQ@mail.gmail.com","threadId":"60056","inReplyTo":"CAOLTT8RvAbmS1SwFja8_+NSBBoL0gTH1RgpSN5CYtDWZscMYZA@mail.gmail.com","subject":"Re: [Question] git rev-parse verify for non-existent object","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2023-08-02T10:24:47Z","receivedAt":"2023-08-02T10:30:00Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, Aug 2, 2023 at 9:50 AM ZheNing Hu <adlternative@gmail.com> wrote:\n>\n> In my case, I often need to use \"git rev-parse --verify\" to verify\n> if a revision exists in the repository, and this usually works:\n>\n> git rev-parse --verify HEAD\n> afa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n>\n> git rev-parse --verify afa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n> afa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n>\n> git rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n> fatal: Needed a single revision\n>\n> However, when I started checking for a non-existent OID that happened\n> to be exactly 40 characters long, something unexpected happened.\n>  \"git rev-parse --verify\" did not produce any error messages.\n> I consider this to be a BUG.\n>\n> git rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\nThe doc says:\n\n\"\n      --verify\n          Verify that exactly one parameter is provided, and that it\ncan be turned into a raw 20-byte SHA-1 that can be used to access the\nobject database. If so, emit it to the standard output;\n          otherwise, error out.\n\n          If you want to make sure that the output actually names an\nobject in your object database and/or can be used as a specific type\nof object you require, you can add the ^{type} peeling\n          operator to the parameter. For example, git rev-parse\n\"$VAR^{commit}\" will make sure $VAR names an existing object that is a\ncommit-ish (i.e. a commit, or an annotated tag that points\n          at a commit). To make sure that $VAR names an existing\nobject of any type, git rev-parse \"$VAR^{object}\" can be used.\n\"\n\nSo \"--verify <argument>\" only checks that the <argument> provided to\nit can be turned into a raw 20-byte SHA-1 (or perhaps a raw 32-byte\nSHA256 in case the repo is using SHA256). \"^{object}\" should be added\nat the end of the <argument> if you want to verify that the raw\n20-byte SHA-1 (or the raw 32-byte SHA256) also corresponds to an\nactual object in the repo.\n\n$ git rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^{object}\nfatal: Needed a single revision\n\nHope this helps.\n"},{"id":"480095","messageId":"CAOLTT8TXYpyadp=Z6K44G59iSar5ieyLwmSph4ypwxGo9doHYA@mail.gmail.com","threadId":"60056","inReplyTo":"CAP8UFD02tYrz+bxoR_GQfYuxxrmv5=BXjcZuiqXbX3m7N2dPaQ@mail.gmail.com","subject":"Re: [Question] git rev-parse verify for non-existent object","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-08-02T13:03:25Z","receivedAt":"2023-08-02T13:03:40Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Christian Couder <christian.couder@gmail.com> 于2023年8月2日周三 18:25写道：\n>\n> On Wed, Aug 2, 2023 at 9:50 AM ZheNing Hu <adlternative@gmail.com> wrote:\n> >\n> > In my case, I often need to use \"git rev-parse --verify\" to verify\n> > if a revision exists in the repository, and this usually works:\n> >\n> > git rev-parse --verify HEAD\n> > afa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n> >\n> > git rev-parse --verify afa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n> > afa5ff0f56bc60d1c9abe839726e7fb2105a9ca3\n> >\n> > git rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n> > fatal: Needed a single revision\n> >\n> > However, when I started checking for a non-existent OID that happened\n> > to be exactly 40 characters long, something unexpected happened.\n> >  \"git rev-parse --verify\" did not produce any error messages.\n> > I consider this to be a BUG.\n> >\n> > git rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n> > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n>\n> The doc says:\n>\n> \"\n>       --verify\n>           Verify that exactly one parameter is provided, and that it\n> can be turned into a raw 20-byte SHA-1 that can be used to access the\n> object database. If so, emit it to the standard output;\n>           otherwise, error out.\n>\n\nSo why doesn't \"git rev-list --verify\" check if 20-byte SHA-1 can\n \"access the object database\"?\n\n>           If you want to make sure that the output actually names an\n> object in your object database and/or can be used as a specific type\n> of object you require, you can add the ^{type} peeling\n>           operator to the parameter. For example, git rev-parse\n> \"$VAR^{commit}\" will make sure $VAR names an existing object that is a\n> commit-ish (i.e. a commit, or an annotated tag that points\n>           at a commit). To make sure that $VAR names an existing\n> object of any type, git rev-parse \"$VAR^{object}\" can be used.\n> \"\n>\n> So \"--verify <argument>\" only checks that the <argument> provided to\n> it can be turned into a raw 20-byte SHA-1 (or perhaps a raw 32-byte\n> SHA256 in case the repo is using SHA256). \"^{object}\" should be added\n> at the end of the <argument> if you want to verify that the raw\n> 20-byte SHA-1 (or the raw 32-byte SHA256) also corresponds to an\n> actual object in the repo.\n>\n> $ git rev-parse --verify aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^{object}\n> fatal: Needed a single revision\n>\n> Hope this helps.\n\nThank you, your method is effective for me.\n"},{"id":"480096","messageId":"xmqq1qgl9zgm.fsf@gitster.g","threadId":"60056","inReplyTo":"CAOLTT8TXYpyadp=Z6K44G59iSar5ieyLwmSph4ypwxGo9doHYA@mail.gmail.com","subject":"Re: [Question] git rev-parse verify for non-existent object","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-08-02T16:32:57Z","receivedAt":"2023-08-02T16:33:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"ZheNing Hu <adlternative@gmail.com> writes:\n\n>>       --verify\n>>           Verify that exactly one parameter is provided, and that it\n>> can be turned into a raw 20-byte SHA-1 that can be used to access the\n>> object database. If so, emit it to the standard output;\n>>           otherwise, error out.\n>>\n>\n> So why doesn't \"git rev-list --verify\" check if 20-byte SHA-1 can\n>  \"access the object database\"?\n\nHysterical Raisins.\n\n\"rev-parse\" can do many things, and one of them is about expanding\nstrings (like \"9e4df4da\", \"jt/path-filter-fix\", \"seen~7^2\", and\n\"9e4df4da0786797b1d51ed8fd3dfc18970772a91\") given from the command\nline into hexadecimal strings of the full length (they are often\ncalled \"revision\").  \"--verify\" tells the command that on the\ncommand line there must be ONE and only one \"revision\", give the\nfull length hexadecimal string for it.  The command fails if the\ncommand line argument cannot be turned into a hexadecimal string of\nthe full length.\n\nNow, among the ones given as examples in the above, \"9e4df4da\",\nneeds to look at the object database to turn it into a hexadecimal\nstring of the full length, because it is likely to be an abbrevation\n(although it could be a branch name, too).  \"jt/path-filter-fix\" and\n\"seen~7^2\" needs to look at the refs and probably into the object\ndatabase (to see what the 7th generation grandparent is and what the\nsecond parent of that commit is) before they can be turned into\nhexadecimal strings of the full length.\n\nBut \"9e4df4da0786797b1d51ed8fd3dfc18970772a91\" is already a full\nhexadecimal, so it is given back as a \"revision\" without checking if\nthere is such an object in the object database.\n\nChecking if it can be turned into the form that can be used to query\nthe object database, and checking the object database using it to\nfind out if such an object exists, are two distinct steps low-level\ntool authors, who would want to use the plumbing tools, may need.\nThe current option set allows the separation (and ^{object} suffix\nlets you do the both at the same time, too).\n\n"},{"id":"480114","messageId":"CAOLTT8Sht6xsVDOmEdGow8wrHvDDdEx7fDyqXC31MOTxVkSifg@mail.gmail.com","threadId":"60056","inReplyTo":"xmqq1qgl9zgm.fsf@gitster.g","subject":"Re: [Question] git rev-parse verify for non-existent object","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2023-08-03T06:16:30Z","receivedAt":"2023-08-03T06:16:46Z","isPatch":false,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Junio C Hamano <gitster@pobox.com> 于2023年8月3日周四 00:32写道：\n>\n> ZheNing Hu <adlternative@gmail.com> writes:\n>\n> >>       --verify\n> >>           Verify that exactly one parameter is provided, and that it\n> >> can be turned into a raw 20-byte SHA-1 that can be used to access the\n> >> object database. If so, emit it to the standard output;\n> >>           otherwise, error out.\n> >>\n> >\n> > So why doesn't \"git rev-list --verify\" check if 20-byte SHA-1 can\n> >  \"access the object database\"?\n>\n> Hysterical Raisins.\n>\n> \"rev-parse\" can do many things, and one of them is about expanding\n> strings (like \"9e4df4da\", \"jt/path-filter-fix\", \"seen~7^2\", and\n> \"9e4df4da0786797b1d51ed8fd3dfc18970772a91\") given from the command\n> line into hexadecimal strings of the full length (they are often\n> called \"revision\").  \"--verify\" tells the command that on the\n> command line there must be ONE and only one \"revision\", give the\n> full length hexadecimal string for it.  The command fails if the\n> command line argument cannot be turned into a hexadecimal string of\n> the full length.\n>\n> Now, among the ones given as examples in the above, \"9e4df4da\",\n> needs to look at the object database to turn it into a hexadecimal\n> string of the full length, because it is likely to be an abbrevation\n> (although it could be a branch name, too).  \"jt/path-filter-fix\" and\n> \"seen~7^2\" needs to look at the refs and probably into the object\n> database (to see what the 7th generation grandparent is and what the\n> second parent of that commit is) before they can be turned into\n> hexadecimal strings of the full length.\n>\n> But \"9e4df4da0786797b1d51ed8fd3dfc18970772a91\" is already a full\n> hexadecimal, so it is given back as a \"revision\" without checking if\n> there is such an object in the object database.\n>\n\nWell, so the \"git rev-parse --verify\" command simply converts the revision\ninto a 20-byte SHA-1 without actually performing any real \"verification\", which\ncan be quite misleading.\n\n> Checking if it can be turned into the form that can be used to query\n> the object database, and checking the object database using it to\n> find out if such an object exists, are two distinct steps low-level\n> tool authors, who would want to use the plumbing tools, may need.\n> The current option set allows the separation (and ^{object} suffix\n> lets you do the both at the same time, too).\n>\n\nThanks for the answer.\n"}]}