{"thread":{"id":"48066","subject":"get commit ID from a tree object ID","startedAt":"2018-03-17T12:29:38Z","lastAt":"2018-03-26T22:21:14Z","messageCount":6,"participants":["Michal Novotny","Konstantin Khomoutov","Jeff King","Junio C Hamano","Stefan Beller","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"342017","messageId":"CANT8FXR3pMgbwVWmwssDYhgv6eMFw4+Uz5xARGwFVVU1cMVmWw@mail.gmail.com","threadId":"48066","inReplyTo":null,"subject":"get commit ID from a tree object ID","fromName":"Michal Novotny","fromEmail":"clime@redhat.com","sentAt":"2018-03-17T12:17:12Z","receivedAt":"2018-03-17T12:29:38Z","isPatch":false,"sender":{"key":"clime@redhat.com","avatar":null},"body":"Hello,\n\nlet's say I have made an annotated tag on a certain treeish:\n\n$ git tag -a -m msg tagname HEAD:\n\nNow, I can try to see the content of the tag:\n\n$ git tag -v tagname\nobject 42a1c36553a50ceae2f75ffc4b1446c6c393eae7\ntype tree\ntag tagname\ntagger clime <clime@redhat.com> 1521288727 +0100\n\nmsg\nerror: no signature found\n\n\nCan I use that object ID 42a1c36553a50ceae2f75ffc4b1446c6c393eae7 to\nget back to a particular commit from which the tag was created? The\nreason is that I would eventually like to checkout that commit.\n\nThank you\nclime\n"},{"id":"342018","messageId":"20180317130128.mr2sfsrncykkubwo@tigra","threadId":"48066","inReplyTo":"CANT8FXR3pMgbwVWmwssDYhgv6eMFw4+Uz5xARGwFVVU1cMVmWw@mail.gmail.com","subject":"Re: get commit ID from a tree object ID","fromName":"Konstantin Khomoutov","fromEmail":"kostix@bswap.ru","sentAt":"2018-03-17T13:01:28Z","receivedAt":"2018-03-17T13:01:41Z","isPatch":false,"sender":{"key":"kostix@bswap.ru","avatar":null},"body":"On Sat, Mar 17, 2018 at 01:17:12PM +0100, Michal Novotny wrote:\n\n> let's say I have made an annotated tag on a certain treeish:\n> \n> $ git tag -a -m msg tagname HEAD:\n> \n> Now, I can try to see the content of the tag:\n> \n> $ git tag -v tagname\n> object 42a1c36553a50ceae2f75ffc4b1446c6c393eae7\n> type tree\n> tag tagname\n> tagger clime <clime@redhat.com> 1521288727 +0100\n> \n> msg\n> error: no signature found\n> \n> \n> Can I use that object ID 42a1c36553a50ceae2f75ffc4b1446c6c393eae7 to\n> get back to a particular commit from which the tag was created? The\n> reason is that I would eventually like to checkout that commit.\n\nIn general, you can't, and that's because there can be any number of\ncommits referencing that tree. A typical case is a tree object\nrepresenting a subdirectory of your project which changes rarily, if\never - in this case, each commit which includes the same state of this\nsubdirectory will refer the same tree object.\n\nAnother point to consider is that the commit itself only refers to a\nsingle tree object -- that one which records the state of the top-level\nproject directory, and it usually refers to other three objects which\nmay, in turn, refer to others and so on - all the way down.\n\nSo actually a generic approach to what you need is a full scan of all\nthe commits in the repository with recursive traversing of the hierarchy\nof trees of each of them (via `git ls-tree`) and looking for the SHA-1\nname of the reference tree object.  As you can see, this is not going to\nbe fast on repos of realistic size.\n\n"},{"id":"342037","messageId":"20180317161819.GB25113@sigill.intra.peff.net","threadId":"48066","inReplyTo":"20180317130128.mr2sfsrncykkubwo@tigra","subject":"Re: get commit ID from a tree object ID","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-03-17T16:18:19Z","receivedAt":"2018-03-17T16:18:26Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Mar 17, 2018 at 04:01:28PM +0300, Konstantin Khomoutov wrote:\n\n> So actually a generic approach to what you need is a full scan of all\n> the commits in the repository with recursive traversing of the hierarchy\n> of trees of each of them (via `git ls-tree`) and looking for the SHA-1\n> name of the reference tree object.  As you can see, this is not going to\n> be fast on repos of realistic size.\n\nIf you assume that the tree is a root tree (which is by no means\ncertain, but a good guess), it's not _too_ bad to do:\n\n  git rev-list --all --format='%T %H' | grep ^$desired_tree\n\nThat's linear in the number of commits, but still takes only about 7\nseconds on linux.git.\n\nIf you want to dig further, you can use the diff machinery to show which\ncommit introduced a particular tree, like:\n\n  git rev-list --all |\n  git diff-tree --stdin --pretty=raw --raw -t -r |\n  less +/$desired_tree\n\nThat \"less\" will find the mentioned tree, and then you'll have to\nmanually read the commit. It would be possible to do it mechanically\nwith a short perl script, but I'll leave that as an exercise for the\nreader.\n\n-Peff\n"},{"id":"342038","messageId":"xmqqwoyay48n.fsf@gitster-ct.c.googlers.com","threadId":"48066","inReplyTo":"20180317161819.GB25113@sigill.intra.peff.net","subject":"Re: get commit ID from a tree object ID","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-03-17T17:57:28Z","receivedAt":"2018-03-17T17:57:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> If you want to dig further, you can use the diff machinery to show which\n> commit introduced a particular tree, like:\n>\n>   git rev-list --all |\n>   git diff-tree --stdin --pretty=raw --raw -t -r |\n>   less +/$desired_tree\n>\n> That \"less\" will find the mentioned tree, and then you'll have to\n> manually read the commit. It would be possible to do it mechanically\n> with a short perl script, but I'll leave that as an exercise for the\n> reader.\n\nBefore Stefan jumps in ;-) I wonder if a recently materialized\n\"find-object\" option to the diff family can be used here as a\nsugar-coated way.\n"},{"id":"343080","messageId":"CAGZ79kZU39B42BeOxrUDxT6Nca0=Yd+O0TEgu6_HvK3O=b2KhQ@mail.gmail.com","threadId":"48066","inReplyTo":"xmqqwoyay48n.fsf@gitster-ct.c.googlers.com","subject":"Re: get commit ID from a tree object ID","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-03-26T22:14:52Z","receivedAt":"2018-03-26T22:15:08Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Sat, Mar 17, 2018 at 10:57 AM Junio C Hamano <gitster@pobox.com> wrote:\n\n> Jeff King <peff@peff.net> writes:\n\n> > If you want to dig further, you can use the diff machinery to show which\n> > commit introduced a particular tree, like:\n> >\n> >   git rev-list --all |\n> >   git diff-tree --stdin --pretty=raw --raw -t -r |\n> >   less +/$desired_tree\n> >\n> > That \"less\" will find the mentioned tree, and then you'll have to\n> > manually read the commit. It would be possible to do it mechanically\n> > with a short perl script, but I'll leave that as an exercise for the\n> > reader.\n\n> Before Stefan jumps in ;-) I wonder if a recently materialized\n> \"find-object\" option to the diff family can be used here as a\n> sugar-coated way.\n\nI am late to jump in, but testing the 'git log --find-object'\nseems to have issues with trees named by sha1 here,\nbut the named tree via <commit>:<path> still seems to work.\n\nIt seems reasonable to be able to find trees using the find-object\nflag, though.\n\nStefan\n"},{"id":"343082","messageId":"20180326222106.GC21735@aiede.svl.corp.google.com","threadId":"48066","inReplyTo":"CAGZ79kZU39B42BeOxrUDxT6Nca0=Yd+O0TEgu6_HvK3O=b2KhQ@mail.gmail.com","subject":"Re: get commit ID from a tree object ID","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2018-03-26T22:21:06Z","receivedAt":"2018-03-26T22:21:14Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nStefan Beller wrote:\n> On Sat, Mar 17, 2018 at 10:57 AM Junio C Hamano <gitster@pobox.com> wrote:\n>> Jeff King <peff@peff.net> writes:\n\n>>> If you want to dig further, you can use the diff machinery to show which\n>>> commit introduced a particular tree, like:\n>>>\n>>>   git rev-list --all |\n>>>   git diff-tree --stdin --pretty=raw --raw -t -r |\n>>>   less +/$desired_tree\n>>>\n>>> That \"less\" will find the mentioned tree, and then you'll have to\n>>> manually read the commit. It would be possible to do it mechanically\n>>> with a short perl script, but I'll leave that as an exercise for the\n>>> reader.\n>\n>> Before Stefan jumps in ;-) I wonder if a recently materialized\n>> \"find-object\" option to the diff family can be used here as a\n>> sugar-coated way.\n>\n> I am late to jump in, but testing the 'git log --find-object'\n> seems to have issues with trees named by sha1 here,\n> but the named tree via <commit>:<path> still seems to work.\n\nExperimenting a little more, I wondered if \"-t\" wasn't being passed\nby default:\n\n  $ git --oneline log -t --find-object=$(git rev-parse HEAD~30:Documentation/technical)\n  $\n\nNo, that's not it.  Could it have to do with merges?\n\n  $ git log --oneline -m --first-parent --find-object=$(git rev-parse HEAD~30:Documentation/technical)\n  df6cfe8c30 Merge branch 'debian-experimental' into google3\n  f86d5fd2e4 Merge branch 'debian-experimental' into google3\n\nYes.\n\nThat doesn't explain why <commit>:<path> worked for you, though. :)\n\nThanks,\nJonathan\n"}]}