{"thread":{"id":"29408","subject":"[Q] Determing if a commit is reachable from the HEAD ?","startedAt":"2012-01-20T13:33:29Z","lastAt":"2012-01-24T08:56:15Z","messageCount":12,"participants":["Brian Foster","Andreas Schwab","David Brown","Junio C Hamano","Sitaram Chamarty"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"182852","messageId":"201201201433.30267.brian.foster@maxim-ic.com","threadId":"29408","inReplyTo":null,"subject":"[Q] Determing if a commit is reachable from the HEAD ?","fromName":"Brian Foster","fromEmail":"brian.foster@maxim-ic.com","sentAt":"2012-01-20T13:33:29Z","receivedAt":"2012-01-20T13:33:29Z","isPatch":false,"sender":{"key":"brian.foster@maxim-ic.com","avatar":null},"body":"\nHello,\n\n Whilst I have found answers to my question on the Web,\n only one seems to do exactly what I want ....\n\n                         x---Y---y---y---y  HEAD\n                        /\n  ...--o---o---C---o---S\n                        \\\n                         n---n---N---*---*  other\n\n In a script, how can I determine commit Y is reachable\n from the current HEAD ?   And, much more importantly\n for my purposes, that commit N is _not_-reachable from\n the current HEAD ?  \"A is reachable from B\" meaning B\n is an ancestor of A (B could possibly part of a merge\n (not shown in the above diagram)):\n\n  ✓ Commits o(all), C, S, x, y(all), and Y: YES  (reachable).\n  ✗ Commits n(all), N, and *(all): NO  (not-reachable).\n\n The only readily script-able answer I've found is to use\n `git branch --contains=Y' and check to see if the current\n branch (conveniently marked `*') is/isn't included in the\n output.  That is probably Ok, but I'm wondering if there\n is some \"better\" method (with the IMPORTANT caveat it must\n work with GIT 1.5.x or later  ;-\\ ).\n\n git-rev-list(1) may be a answer (see script below), but ....\n `git rev-list ^Y HEAD' lists all the y commits, which is Ok\n (correct for my purposes).  However, `git rev-list ^N HEAD'\n lists commits x, Y, and y(all) on branch \"other\", which is\n not-Ok:  As per above, the answer I want is \"NO\".\n\n Apologies if I've overlooked something totally obvious !\n\ncheers,\n\t-blf-\n\n=====(cut here and below)=====reach02.sh=====\n#!/bin/bash\n#\n#                         x---Y---y---y---y  HEAD\n#                        /\n#  ...--o---o---C---o---S\n#                        \\\n#                         n---n---N---*---*  other\n#\n\n: ${GIT:=git}\t# Allow use of different installed GIT versions.\n\nupdate_file() {\n\tdate +\"%c: $*\" >>file\n\t$GIT add file  &&  $GIT commit -m \"$*\" file\n}\n\nset -e\t\t# Terminate if problem creating diagrammed situation.\n\nrm -rf -- reachable\nmkdir  -- reachable\ncd reachable\n\n$GIT version\n$GIT init\n\nupdate_file     o1\nupdate_file     o2\nupdate_file \"C (o3)\";\t$GIT tag C\nupdate_file     o4\nupdate_file \"S (o5)\";\t$GIT tag S\n\n$GIT checkout -b other\nupdate_file     n1\nupdate_file     n2\nupdate_file \"N (n3)\";\t$GIT tag N\nupdate_file    \"*1\"\nupdate_file    \"*2\"\n\n$GIT checkout master\nupdate_file     x\nupdate_file \"Y (y1)\";\t$GIT tag Y\nupdate_file     y2\nupdate_file     y3\nupdate_file     y4\n\ndeclare -i wrong=0\n\necho \"Is Y reachable from HEAD?  Wanted answer: Yes.\"\n$GIT log --oneline ^Y HEAD\nif $GIT rev-list --quiet ^Y HEAD; then\n\techo \"rev-list: YES (wanted answer)!\"\nelse\n\techo \"rev-list: No! *** not-wanted, oops... ***\"\n\twrong=$(( wrong + 1 ))\nfi\nif $GIT branch --contains=Y | grep -q -e '^\\*'; then\n\techo \"contains: YES (wanted answer)!\"\nelse\n\techo \"contains: No! *** not-wanted, oops... ***\"\n\twrong=$(( wrong + 1 ))\nfi\n\necho \"Is N reachable from HEAD?  Wanted answer: No.\"\n$GIT log --oneline ^N HEAD\nif $GIT rev-list --quiet ^N HEAD; then\n\techo \"rev-list: YES? *** not-wanted, oops... ***\"\n\twrong=$(( wrong + 1 ))\nelse\n\techo \"rev-list: No (wanted answer)!\"\nfi\nif $GIT branch --contains=N | grep -q -e '^\\*'; then\n\techo \"contains: YES? *** not-wanted, oops... ***\"\n\twrong=$(( wrong + 1 ))\nelse\n\techo \"contains: No (wanted answer)!\"\nfi\n\nexit $wrong\n=====(cut here and above)=====reach02.sh=====\n\n-- \nBrian Foster\nPrincipal MTS, Software        |  La Ciotat, France\nMaxim Integrated Products      |  Web:  http://www.maxim-ic.com/\n"},{"id":"182855","messageId":"m2ehuu8nrt.fsf@igel.home","threadId":"29408","inReplyTo":"201201201433.30267.brian.foster@maxim-ic.com","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2012-01-20T14:13:58Z","receivedAt":"2012-01-20T14:13:58Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Brian Foster <brian.foster@maxim-ic.com> writes:\n\n>  In a script, how can I determine commit Y is reachable\n>  from the current HEAD ?\n\ntest $(git merge-base HEAD Y) = $(git rev-parse Y)\n\n>  And, much more importantly\n>  for my purposes, that commit N is _not_-reachable from\n>  the current HEAD ?\n\ntest $(git merge-base HEAD N) != $(git rev-parse N)\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"182863","messageId":"20120120180620.GA8504@codeaurora.org","threadId":"29408","inReplyTo":"m2ehuu8nrt.fsf@igel.home","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"David Brown","fromEmail":"davidb@codeaurora.org","sentAt":"2012-01-20T18:06:20Z","receivedAt":"2012-01-20T18:06:20Z","isPatch":false,"sender":{"key":"davidb@codeaurora.org","avatar":"https://gravatar.com/avatar/1bacedec21621bd4efa4bc8ecb05c507f0cf0641ecdaa50943c2ed21c8ef22d8?d=mp&s=160"},"body":"On Fri, Jan 20, 2012 at 03:13:58PM +0100, Andreas Schwab wrote:\n> Brian Foster <brian.foster@maxim-ic.com> writes:\n> \n> >  In a script, how can I determine commit Y is reachable\n> >  from the current HEAD ?\n> \n> test $(git merge-base HEAD Y) = $(git rev-parse Y)\n\nAlmost.  It works as long as there is only one merge base.  You really\nneed to check if $(git rev-parse Y) is one of $(git merge-base --all\nHEAD Y)\n\nif HEAD is a named branch, you can do\n\n  git name-rev --refs=refs/heads/branchname Y\n\nwhich will give you Y relative to branchname if it is contained within\nit.\n\nDavid\n\n-- \nSent by an employee of the Qualcomm Innovation Center, Inc.\nThe Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.\n"},{"id":"182868","messageId":"7v7h0mfahx.fsf@alter.siamese.dyndns.org","threadId":"29408","inReplyTo":"20120120180620.GA8504@codeaurora.org","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-20T19:18:50Z","receivedAt":"2012-01-20T19:18:50Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Brown <davidb@codeaurora.org> writes:\n\n> On Fri, Jan 20, 2012 at 03:13:58PM +0100, Andreas Schwab wrote:\n>> Brian Foster <brian.foster@maxim-ic.com> writes:\n>> \n>> >  In a script, how can I determine commit Y is reachable\n>> >  from the current HEAD ?\n>> \n>> test $(git merge-base HEAD Y) = $(git rev-parse Y)\n>\n> Almost.  It works as long as there is only one merge base.  You really\n> need to check if $(git rev-parse Y) is one of $(git merge-base --all\n> HEAD Y)\n\nCan you give us an example of a topology to which \"merge-base --all HEAD Y\"\ngives more than one output and Y is still reachable from HEAD?\n\nIt is my understanding that merge-base computation will give only Y and\nnothing else when Y is reachable from HEAD. I also think this assumption\nis used by some of the internal code in Git, and that is why I care.\n"},{"id":"182881","messageId":"CAMK1S_gkZYpK3nrNMsnmFzi=tzjyEjVwOo_j4Z=d0hqjdF7r_w@mail.gmail.com","threadId":"29408","inReplyTo":"201201201433.30267.brian.foster@maxim-ic.com","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2012-01-20T22:50:23Z","receivedAt":"2012-01-20T22:50:23Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On Fri, Jan 20, 2012 at 7:03 PM, Brian Foster <brian.foster@maxim-ic.com> wrote:\n>\n> Hello,\n>\n>  Whilst I have found answers to my question on the Web,\n>  only one seems to do exactly what I want ....\n>\n>                         x---Y---y---y---y  HEAD\n>                        /\n>  ...--o---o---C---o---S\n>                        \\\n>                         n---n---N---*---*  other\n>\n>  In a script, how can I determine commit Y is reachable\n>  from the current HEAD ?   And, much more importantly\n\nI've been using 'git rev-list HEAD..Y'.  If it produces any output, Y\nis not reachable from HEAD (there is something in Y that is not in\nHEAD).\n"},{"id":"182882","messageId":"20120120233335.GA20302@codeaurora.org","threadId":"29408","inReplyTo":"7v7h0mfahx.fsf@alter.siamese.dyndns.org","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"David Brown","fromEmail":"davidb@codeaurora.org","sentAt":"2012-01-20T23:33:35Z","receivedAt":"2012-01-20T23:33:35Z","isPatch":false,"sender":{"key":"davidb@codeaurora.org","avatar":"https://gravatar.com/avatar/1bacedec21621bd4efa4bc8ecb05c507f0cf0641ecdaa50943c2ed21c8ef22d8?d=mp&s=160"},"body":"On Fri, Jan 20, 2012 at 11:18:50AM -0800, Junio C Hamano wrote:\n> David Brown <davidb@codeaurora.org> writes:\n> \n> > On Fri, Jan 20, 2012 at 03:13:58PM +0100, Andreas Schwab wrote:\n> >> Brian Foster <brian.foster@maxim-ic.com> writes:\n> >> \n> >> >  In a script, how can I determine commit Y is reachable\n> >> >  from the current HEAD ?\n> >> \n> >> test $(git merge-base HEAD Y) = $(git rev-parse Y)\n> >\n> > Almost.  It works as long as there is only one merge base.  You really\n> > need to check if $(git rev-parse Y) is one of $(git merge-base --all\n> > HEAD Y)\n> \n> Can you give us an example of a topology to which \"merge-base --all HEAD Y\"\n> gives more than one output and Y is still reachable from HEAD?\n> \n> It is my understanding that merge-base computation will give only Y and\n> nothing else when Y is reachable from HEAD. I also think this assumption\n> is used by some of the internal code in Git, and that is why I care.\n\nHmm, I thought I'd convinced myself that this was possible.  Now, I\ncan't come up with a way of doing it that doesn't involve improper\ncommits with earlier timestamps than their parents.\n\nSorry about that,\nDavid\n\n-- \nSent by an employee of the Qualcomm Innovation Center, Inc.\nThe Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.\n"},{"id":"182883","messageId":"7vzkdhdiot.fsf@alter.siamese.dyndns.org","threadId":"29408","inReplyTo":"20120120233335.GA20302@codeaurora.org","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-21T00:04:50Z","receivedAt":"2012-01-21T00:04:50Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Brown <davidb@codeaurora.org> writes:\n\n> Hmm, I thought I'd convinced myself that this was possible.  Now, I\n> can't come up with a way of doing it that doesn't involve improper\n> commits with earlier timestamps than their parents.\n\nI'd actually want to see a way to do so that *does* involve timestamp\nskew.\n"},{"id":"182894","messageId":"20120121045803.GA29328@codeaurora.org","threadId":"29408","inReplyTo":"7vzkdhdiot.fsf@alter.siamese.dyndns.org","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"David Brown","fromEmail":"davidb@codeaurora.org","sentAt":"2012-01-21T04:58:03Z","receivedAt":"2012-01-21T04:58:03Z","isPatch":false,"sender":{"key":"davidb@codeaurora.org","avatar":"https://gravatar.com/avatar/1bacedec21621bd4efa4bc8ecb05c507f0cf0641ecdaa50943c2ed21c8ef22d8?d=mp&s=160"},"body":"On Fri, Jan 20, 2012 at 04:04:50PM -0800, Junio C Hamano wrote:\n> David Brown <davidb@codeaurora.org> writes:\n> \n> > Hmm, I thought I'd convinced myself that this was possible.  Now, I\n> > can't come up with a way of doing it that doesn't involve improper\n> > commits with earlier timestamps than their parents.\n> \n> I'd actually want to see a way to do so that *does* involve timestamp\n> skew.\n\nSorry, I guess I shouldn't tried this with a recent version of git.  I\ncan't cause this, and it looks like there's some pretty sophisticated\nstuff in there to deal with this.\n\nDavid\n\n-- \nSent by an employee of the Qualcomm Innovation Center, Inc.\nThe Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.\n"},{"id":"182954","messageId":"201201231020.04041.brian.foster@maxim-ic.com","threadId":"29408","inReplyTo":"CAMK1S_gkZYpK3nrNMsnmFzi=tzjyEjVwOo_j4Z=d0hqjdF7r_w@mail.gmail.com","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Brian Foster","fromEmail":"brian.foster@maxim-ic.com","sentAt":"2012-01-23T09:20:03Z","receivedAt":"2012-01-23T09:20:03Z","isPatch":false,"sender":{"key":"brian.foster@maxim-ic.com","avatar":null},"body":"On Friday 20 January 2012 23:50:23 Sitaram Chamarty wrote:\n> On Fri, Jan 20, 2012 at 7:03 PM, Brian Foster <brian.foster@maxim-ic.com> wrote:\n>[ ... ]\n> >                         x---Y---y---y---y  HEAD\n> >                        /\n> >  ...--o---o---C---o---S\n> >                        \\\n> >                         n---n---N---*---*  other\n> >\n> >  In a script, how can I determine commit Y is reachable\n> >  from the current HEAD ?   [ ... ]\n> \n> I've been using 'git rev-list HEAD..Y'.  If it produces any output,\n> Y is not reachable from HEAD (there is something in Y that is not\n> in HEAD).\n\n What's interesting about this solution, at least\n with GIT v1.7.6.1 (I haven't tried other versions),\n is ‘git rev-list HEAD..Y’ does seem to work (if\n there is any output, then Y is not reachable from\n HEAD), but ‘git rev-list --quiet HEAD..Y’ does _not_\n work (it seems to always(?) exit status 0).\n\n I am probably misunderstanding ‘--quiet’, which the\n man page cryptically describes as “... allow the\n caller to test the exit status to see if a range\n of objects is fully connected (or not).”  What is\n meant here by “fully connected” ?\n\ncheers!\n\t-blf-\n\n-- \nBrian Foster\nPrincipal MTS, Software        |  La Ciotat, France\nMaxim Integrated Products      |  Web:  http://www.maxim-ic.com/\n"},{"id":"182969","messageId":"7vk44i9z99.fsf@alter.siamese.dyndns.org","threadId":"29408","inReplyTo":"201201231020.04041.brian.foster@maxim-ic.com","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-23T16:09:38Z","receivedAt":"2012-01-23T16:09:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brian Foster <brian.foster@maxim-ic.com> writes:\n\n>  I am probably misunderstanding ‘--quiet’, which the\n>  man page cryptically describes as “... allow the\n>  caller to test the exit status to see if a range\n>  of objects is fully connected (or not).”  What is\n>  meant here by “fully connected” ?\n\nIf the real history looks like this:\n\n ---Y---x---HEAD\n\ni.e. the commit at HEAD says \"parent x\" in it, and your lacks \"x\"\nfor whatever reason, Y..HEAD is not fully connected.\n"},{"id":"183011","messageId":"201201240916.15630.brian.foster@maxim-ic.com","threadId":"29408","inReplyTo":"7vk44i9z99.fsf@alter.siamese.dyndns.org","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Brian Foster","fromEmail":"brian.foster@maxim-ic.com","sentAt":"2012-01-24T08:16:15Z","receivedAt":"2012-01-24T08:16:15Z","isPatch":false,"sender":{"key":"brian.foster@maxim-ic.com","avatar":null},"body":"On Monday 23 January 2012 17:09:38 Junio C Hamano wrote:\n> Brian Foster <brian.foster@maxim-ic.com> writes:\n> >  I am probably misunderstanding ‘--quiet’, which the\n> >  man page cryptically describes as “... allow the\n> >  caller to test the exit status to see if a range\n> >  of objects is fully connected (or not).”  What is\n> >  meant here by “fully connected” ?\n> \n> If the real history looks like this:\n> \n>  ---Y---x---HEAD\n> \n> i.e. the commit at HEAD says \"parent x\" in it, and your lacks \"x\"\n> for whatever reason, Y..HEAD is not fully connected.\n\nJunio, and my _what_ lacks \"x\"?  Sorry, it looks like\n you typo'ed, but I cannot decipher what you meant.\n\ncheers!\n\t-blf-\n-- \nBrian Foster\nPrincipal MTS, Software        |  La Ciotat, France\nMaxim Integrated Products      |  Web:  http://www.maxim-ic.com/\n"},{"id":"183013","messageId":"201201240956.15624.brian.foster@maxim-ic.com","threadId":"29408","inReplyTo":"7vk44i9z99.fsf@alter.siamese.dyndns.org","subject":"Re: [Q] Determing if a commit is reachable from the HEAD ?","fromName":"Brian Foster","fromEmail":"brian.foster@maxim-ic.com","sentAt":"2012-01-24T08:56:15Z","receivedAt":"2012-01-24T08:56:15Z","isPatch":false,"sender":{"key":"brian.foster@maxim-ic.com","avatar":null},"body":"On Monday 23 January 2012 17:09:38 Junio C Hamano wrote:\n> Brian Foster <brian.foster@maxim-ic.com> writes:\n> >  I am probably misunderstanding ‘--quiet’, which the\n> >  man page cryptically describes as “... allow the\n> >  caller to test the exit status to see if a range\n> >  of objects is fully connected (or not).”  What is\n> >  meant here by “fully connected” ?\n> \n> If the real history looks like this:\n> \n>  ---Y---x---HEAD\n> \n> i.e. the commit at HEAD says \"parent x\" in it, and your [repository]\n> lacks \"x\" for whatever reason, Y..HEAD is not fully connected.\n\n Ah, Ok.  Thanks!  Then YES, I misunderstood ‘--quiet’.\n The man page caused me to think it was functionally\n equivalent to ‘git rev-list STUFF >/dev/null’.\n\ncheers!\n\t-blf-\n\n-- \nBrian Foster\nPrincipal MTS, Software        |  La Ciotat, France\nMaxim Integrated Products      |  Web:  http://www.maxim-ic.com/\n"}]}