{"thread":{"id":"30634","subject":"Finding a branch point in git","startedAt":"2012-05-27T12:37:32Z","lastAt":"2012-06-01T09:15:20Z","messageCount":13,"participants":["Felipe Contreras","Jeff King","Martin Langhoff","PJ Weisberg"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"192267","messageId":"CAMP44s0f7AJPQSTDgvy0U7vx8nxzq2a3vMhSr2Tcc61fetFkJA@mail.gmail.com","threadId":"30634","inReplyTo":null,"subject":"Finding a branch point in git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2012-05-27T12:37:32Z","receivedAt":"2012-05-27T12:37:32Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nWhen discussing git vs. mercurial, and what can mercurial do that git\ncan't, I inevitably see somebody mention that mercurial branches can\nbe used to find the branch point (the point at which a branch started;\neven if it's a long-lived one that has been merged to 'master'\nmultiple times).\n\nThere have been a few solutions in stackoverflow[1], but none that\nwork in all cases.\n\nBut I think I've found an ad-hoc one that uses the commit messages to\nfind the first merge of a branch, and then the merge-base.\n\nFor reference, if somebody is interested:\n\n---\n[alias]\n    branch-point = !sh -c 'merge=$(git rev-list --min-parents=2\n--grep=\"Merge.*$1\" --all | tail -1) && git merge-base $merge^1\n$merge^2'\n---\n\nCheers.\n\n[1] http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git/\n\n-- \nFelipe Contreras\n"},{"id":"192307","messageId":"20120528062026.GB11174@sigill.intra.peff.net","threadId":"30634","inReplyTo":"CAMP44s0f7AJPQSTDgvy0U7vx8nxzq2a3vMhSr2Tcc61fetFkJA@mail.gmail.com","subject":"Re: Finding a branch point in git","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-28T06:20:26Z","receivedAt":"2012-05-28T06:20:26Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, May 27, 2012 at 02:37:32PM +0200, Felipe Contreras wrote:\n\n> When discussing git vs. mercurial, and what can mercurial do that git\n> can't, I inevitably see somebody mention that mercurial branches can\n> be used to find the branch point (the point at which a branch started;\n> even if it's a long-lived one that has been merged to 'master'\n> multiple times).\n> \n> There have been a few solutions in stackoverflow[1], but none that\n> work in all cases.\n> \n> But I think I've found an ad-hoc one that uses the commit messages to\n> find the first merge of a branch, and then the merge-base.\n> \n> For reference, if somebody is interested:\n> \n> ---\n> [alias]\n>     branch-point = !sh -c 'merge=$(git rev-list --min-parents=2\n> --grep=\"Merge.*$1\" --all | tail -1) && git merge-base $merge^1\n> $merge^2'\n> ---\n\nI think this approach works for two-branch cases, but there is some\nsubtlety with the regex. My initial thought was that you were looking\nfor \"Merge 'branch_A'\" in the commit message (and that is what is\nimplied by your stackoverflow response). If you always merge the topic\ninto the main branch, then you will find the first merge. But imagine\nthis history:\n\n-- X -- A -- B -- C -- D --  E  (master)\n         \\         \\        /\n          \\         \\      /\n           G -- H -- I -- J  (branch A)\n\nwhere I is a merge from master to branch A (e.g., for testing), and then\nE is a merge from branch A to master (the actual integration).\n\nSearching for \"Merge 'branch_A'\" will find E, and then you will take\nthe merge base of J and D, which is C. But the answer you want is A.\nHowever, we also say \"Merge master into 'branch_A'\" when HEAD is not\nmaster. So your regex _would_ catch that, and would find I, for which\nthe merge base is A.\n\nWhat about a history with multiple branches?\n\n--X--A--B--C--D----E  (master)\n      \\           /\n       G--H--I---J   (branch X)\n           \\    /\n            K--L    (branch Y)\n\nwhere Y is merged to X (commit J), and then X is merged to master\n(commit E). Searching for the earliest merge mentioning X will find J,\nthe merge between X and Y. But the merge base of its parents is H.\n\nYou can improve your regex by specifying a pair of branches and\nlooking for \"Merge X into master\" and \"Merge master into X\" (IOW, make\nsure we don't see merges between X and other branches). Then you would\nfind E, which yields the correct answer.\n\nThere are also even more complex cases. It doesn't make much sense to\nask about where branch Y split from master, since it actually came from\nbranch X in the above example. But let's say we branched straight from\nmaster, merged our result to X, which got merged to master, and then we\nbuilt some more commits on Y and merged them to master. Like:\n\n--X--A--B--C--D----E--F (master)\n     |\\           /  /\n     | \\         /  /\n      \\ G--H----I  /  (branch X)\n       \\       /  /\n        K--L--M--O  (branch Y)\n\nThe only merge between master and X is F, but its merge base is M. We\nmissed the earlier merge to master because it actually happened across\ntwo different commits.\n\n-Peff\n"},{"id":"192384","messageId":"CAMP44s04msWMOaaH8U30XXg5yXJnEd=bULJ7VPxWSD0Wfh2=EA@mail.gmail.com","threadId":"30634","inReplyTo":"20120528062026.GB11174@sigill.intra.peff.net","subject":"Re: Finding a branch point in git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2012-05-28T12:36:04Z","receivedAt":"2012-05-28T12:36:04Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, May 28, 2012 at 8:20 AM, Jeff King <peff@peff.net> wrote:\n> On Sun, May 27, 2012 at 02:37:32PM +0200, Felipe Contreras wrote:\n>\n>> When discussing git vs. mercurial, and what can mercurial do that git\n>> can't, I inevitably see somebody mention that mercurial branches can\n>> be used to find the branch point (the point at which a branch started;\n>> even if it's a long-lived one that has been merged to 'master'\n>> multiple times).\n>>\n>> There have been a few solutions in stackoverflow[1], but none that\n>> work in all cases.\n>>\n>> But I think I've found an ad-hoc one that uses the commit messages to\n>> find the first merge of a branch, and then the merge-base.\n>>\n>> For reference, if somebody is interested:\n>>\n>> ---\n>> [alias]\n>>     branch-point = !sh -c 'merge=$(git rev-list --min-parents=2\n>> --grep=\"Merge.*$1\" --all | tail -1) && git merge-base $merge^1\n>> $merge^2'\n>> ---\n>\n> I think this approach works for two-branch cases, but there is some\n> subtlety with the regex. My initial thought was that you were looking\n> for \"Merge 'branch_A'\" in the commit message (and that is what is\n> implied by your stackoverflow response). If you always merge the topic\n> into the main branch, then you will find the first merge. But imagine\n> this history:\n>\n> -- X -- A -- B -- C -- D --  E  (master)\n>         \\         \\        /\n>          \\         \\      /\n>           G -- H -- I -- J  (branch A)\n>\n> where I is a merge from master to branch A (e.g., for testing), and then\n> E is a merge from branch A to master (the actual integration).\n>\n> Searching for \"Merge 'branch_A'\" will find E, and then you will take\n> the merge base of J and D, which is C. But the answer you want is A.\n> However, we also say \"Merge master into 'branch_A'\" when HEAD is not\n> master. So your regex _would_ catch that, and would find I, for which\n> the merge base is A.\n\nYeap.\n\n> What about a history with multiple branches?\n>\n> --X--A--B--C--D----E  (master)\n>      \\           /\n>       G--H--I---J   (branch X)\n>           \\    /\n>            K--L    (branch Y)\n>\n> where Y is merged to X (commit J), and then X is merged to master\n> (commit E). Searching for the earliest merge mentioning X will find J,\n> the merge between X and Y. But the merge base of its parents is H.\n>\n> You can improve your regex by specifying a pair of branches and\n> looking for \"Merge X into master\" and \"Merge master into X\" (IOW, make\n> sure we don't see merges between X and other branches). Then you would\n> find E, which yields the correct answer.\n\nYes, but then you would need to specify a second branch. I would avoid\nthat if possible.\n\n> There are also even more complex cases. It doesn't make much sense to\n> ask about where branch Y split from master, since it actually came from\n> branch X in the above example. But let's say we branched straight from\n> master, merged our result to X, which got merged to master, and then we\n> built some more commits on Y and merged them to master. Like:\n>\n> --X--A--B--C--D----E--F (master)\n>     |\\           /  /\n>     | \\         /  /\n>      \\ G--H----I  /  (branch X)\n>       \\       /  /\n>        K--L--M--O  (branch Y)\n>\n> The only merge between master and X is F, but its merge base is M. We\n> missed the earlier merge to master because it actually happened across\n> two different commits.\n\nCases 2) and 3) would work if the search was for \"Merge branch 'X'\",\nbut then case 1) would fail. One possible solution would be to find\nthe earliest \"Merge branch 'X' into (\\w+)\", and then search if there\nare any earlier \"Merge branch '$1' into X\".\n\nThere's also another case that doesn't work:\n\n-- X -- A -- B (master)\n         \\\n          \\\n           C (branch A)\n\nShouldn't be hard to add checks for those cases I think.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"192391","messageId":"20120528190639.GA2478@sigill.intra.peff.net","threadId":"30634","inReplyTo":"CAMP44s04msWMOaaH8U30XXg5yXJnEd=bULJ7VPxWSD0Wfh2=EA@mail.gmail.com","subject":"Re: Finding a branch point in git","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-28T19:06:39Z","receivedAt":"2012-05-28T19:06:39Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:\n\n> > What about a history with multiple branches?\n> >\n> > --X--A--B--C--D----E  (master)\n> >      \\           /\n> >       G--H--I---J   (branch X)\n> >           \\    /\n> >            K--L    (branch Y)\n> [...]\n> \n> Yes, but then you would need to specify a second branch. I would avoid\n> that if possible.\n\nI agree that is less nice. But I don't think the operation is\nwell-defined with a single branch. If you ask for \"when did branch X\nsplit\", then in the above graph it is unclear if you meant \"split from\nmaster\", or \"split from Y\".\n\nMaybe you could assume \"master\", or assume \"git symbolic-ref HEAD\" as\nthe second branch?\n\n> There's also another case that doesn't work:\n> \n> -- X -- A -- B (master)\n>          \\\n>           \\\n>            C (branch A)\n> \n> Shouldn't be hard to add checks for those cases I think.\n\nActually, I think that one extends naturally. They are never merged, so\nyour rev-list never finds a merge commit, and you can just take the\nmerge base of the branch tips.\n\n-Peff\n"},{"id":"192492","messageId":"CAMP44s3pKo-Dzg6bTKNmjFsLSYvUfhXfk9NQJxOBTvFekqgrFA@mail.gmail.com","threadId":"30634","inReplyTo":"20120528062026.GB11174@sigill.intra.peff.net","subject":"Re: Finding a branch point in git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2012-05-30T16:52:15Z","receivedAt":"2012-05-30T16:52:15Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, May 28, 2012 at 8:20 AM, Jeff King <peff@peff.net> wrote:\n\n> There are also even more complex cases. It doesn't make much sense to\n> ask about where branch Y split from master, since it actually came from\n> branch X in the above example. But let's say we branched straight from\n> master, merged our result to X, which got merged to master, and then we\n> built some more commits on Y and merged them to master. Like:\n>\n> --X--A--B--C--D----E--F (master)\n>     |\\           /  /\n>     | \\         /  /\n>      \\ G--H----I  /  (branch X)\n>       \\       /  /\n>        K--L--M--O  (branch Y)\n>\n> The only merge between master and X is F, but its merge base is M. We\n> missed the earlier merge to master because it actually happened across\n> two different commits.\n\nI assume you mean the merge between master and Y.\n\n-- \nFelipe Contreras\n"},{"id":"192497","messageId":"CAMP44s0UBsVicuEcwACsm1zTT_jGau_Q20hJv4J_6uvancYJRQ@mail.gmail.com","threadId":"30634","inReplyTo":"20120528190639.GA2478@sigill.intra.peff.net","subject":"Re: Finding a branch point in git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2012-05-30T17:07:39Z","receivedAt":"2012-05-30T17:07:39Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:\n> On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:\n>\n>> > What about a history with multiple branches?\n>> >\n>> > --X--A--B--C--D----E  (master)\n>> >      \\           /\n>> >       G--H--I---J   (branch X)\n>> >           \\    /\n>> >            K--L    (branch Y)\n>> [...]\n>>\n>> Yes, but then you would need to specify a second branch. I would avoid\n>> that if possible.\n>\n> I agree that is less nice. But I don't think the operation is\n> well-defined with a single branch. If you ask for \"when did branch X\n> split\", then in the above graph it is unclear if you meant \"split from\n> master\", or \"split from Y\".\n\nIf you look from the context that I explained in the first mail; it\nwould be from *any* branch; IOW; find the first commit from branch X\n(G), and then find the parent. That would be the first commit where\nbranch X started.\n\n> Maybe you could assume \"master\", or assume \"git symbolic-ref HEAD\" as\n> the second branch?\n\nNo.\n\nI think it would be easy to support this case if somehow there was a\nway to find all the commits that comprise a branch;\n\n % git log branch ^<any-other-branch>\n\nI could swear I saw such an option, but I've been looking for days and\nI can't find it.\n\nIOW; all the commits were 'git branch --contains' would show 'branch'\nand nothing else.\n\n>> There's also another case that doesn't work:\n>>\n>> -- X -- A -- B (master)\n>>          \\\n>>           \\\n>>            C (branch A)\n>>\n>> Shouldn't be hard to add checks for those cases I think.\n>\n> Actually, I think that one extends naturally. They are never merged, so\n> your rev-list never finds a merge commit, and you can just take the\n> merge base of the branch tips.\n\nSure, I can _just_ do that, but I need to do it :)\n\nSo, here it is... I hope people can find ways to simplify it:\n\nfind_merge ()\n{\n\tlocal selection extra\n\ttest \"$2\" && extra=\" into $2\"\n\tgit rev-list --min-parents=2 --grep=\"Merge branch '$1'$extra\"\n--topo-order ${3:---all} | tail -1\n}\n\nbranch_point ()\n{\n\tlocal first_merge second_merge merge\n\tfirst_merge=$(find_merge $1 \"\" \"$1 $2\")\n\tsecond_merge=$(find_merge $2 $1 $first_merge)\n\tmerge=${second_merge:-$first_merge}\n\n\tif [ \"$merge\" ]; then\n\t\tgit merge-base $merge^1 $merge^2\n\telse\n\t\tgit merge-base $1 $2\n\tfi\n}\n\nAnd I've added tests:\nhttps://raw.github.com/gist/2837595/0734e7f17a4597f81c5129e3cbfee09a183e93cd/branch-point\n\nSeems to work :)\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"192513","messageId":"20120530214522.GA3237@sigill.intra.peff.net","threadId":"30634","inReplyTo":"CAMP44s3pKo-Dzg6bTKNmjFsLSYvUfhXfk9NQJxOBTvFekqgrFA@mail.gmail.com","subject":"Re: Finding a branch point in git","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-30T21:45:22Z","receivedAt":"2012-05-30T21:45:22Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 30, 2012 at 06:52:15PM +0200, Felipe Contreras wrote:\n\n> > --X--A--B--C--D----E--F (master)\n> >     |\\           /  /\n> >     | \\         /  /\n> >      \\ G--H----I  /  (branch X)\n> >       \\       /  /\n> >        K--L--M--O  (branch Y)\n> >\n> > The only merge between master and X is F, but its merge base is M. We\n> > missed the earlier merge to master because it actually happened across\n> > two different commits.\n> \n> I assume you mean the merge between master and Y.\n\nOops, yes.\n\n-Peff\n"},{"id":"192515","messageId":"20120530215415.GB3237@sigill.intra.peff.net","threadId":"30634","inReplyTo":"CAMP44s0UBsVicuEcwACsm1zTT_jGau_Q20hJv4J_6uvancYJRQ@mail.gmail.com","subject":"Re: Finding a branch point in git","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-30T21:54:15Z","receivedAt":"2012-05-30T21:54:15Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:\n\n> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:\n> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:\n> >\n> >> > What about a history with multiple branches?\n> >> >\n> >> > --X--A--B--C--D----E  (master)\n> >> >      \\           /\n> >> >       G--H--I---J   (branch X)\n> >> >           \\    /\n> >> >            K--L    (branch Y)\n> >> [...]\n> >>\n> >> Yes, but then you would need to specify a second branch. I would avoid\n> >> that if possible.\n> >\n> > I agree that is less nice. But I don't think the operation is\n> > well-defined with a single branch. If you ask for \"when did branch X\n> > split\", then in the above graph it is unclear if you meant \"split from\n> > master\", or \"split from Y\".\n> \n> If you look from the context that I explained in the first mail; it\n> would be from *any* branch; IOW; find the first commit from branch X\n> (G), and then find the parent. That would be the first commit where\n> branch X started.\n\nI'm not sure that's possible, though, in the face of criss-cross merges.\nHow do we distinguish the history above from one in which branch Y was\nforked from master at G, and then branch X was forked from branch Y at\nH?\n\n> I think it would be easy to support this case if somehow there was a\n> way to find all the commits that comprise a branch;\n> \n>  % git log branch ^<any-other-branch>\n> \n> I could swear I saw such an option, but I've been looking for days and\n> I can't find it.\n\nI don't think there is such an option. You have to do something like:\n\n  {\n    echo \"--not\"\n    git for-each-ref --format='%(refname)' | grep -v \"^$branch\\$\"\n  } |\n  git rev-list --stdin $branch\n\n-Peff\n"},{"id":"192597","messageId":"CAMP44s1Q26B9hCdubfDiP2_YUUWGOtyyA=gSwqpGOE4FfZrN8A@mail.gmail.com","threadId":"30634","inReplyTo":"20120530215415.GB3237@sigill.intra.peff.net","subject":"Re: Finding a branch point in git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2012-05-31T15:27:59Z","receivedAt":"2012-05-31T15:27:59Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:\n> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:\n>\n>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:\n>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:\n>> >\n>> >> > What about a history with multiple branches?\n>> >> >\n>> >> > --X--A--B--C--D----E  (master)\n>> >> >      \\           /\n>> >> >       G--H--I---J   (branch X)\n>> >> >           \\    /\n>> >> >            K--L    (branch Y)\n>> >> [...]\n>> >>\n>> >> Yes, but then you would need to specify a second branch. I would avoid\n>> >> that if possible.\n>> >\n>> > I agree that is less nice. But I don't think the operation is\n>> > well-defined with a single branch. If you ask for \"when did branch X\n>> > split\", then in the above graph it is unclear if you meant \"split from\n>> > master\", or \"split from Y\".\n>>\n>> If you look from the context that I explained in the first mail; it\n>> would be from *any* branch; IOW; find the first commit from branch X\n>> (G), and then find the parent. That would be the first commit where\n>> branch X started.\n>\n> I'm not sure that's possible, though, in the face of criss-cross merges.\n> How do we distinguish the history above from one in which branch Y was\n> forked from master at G, and then branch X was forked from branch Y at\n> H?\n\nThat is true, but we could use the algorithm used by name-rev: G would\nhave a distance 3 from branch X, and distance 2 from Y, so it would be\nconsidered part of branch Y.\n\nSure, it's not possible to know _for sure_, but this is a bit like\nrenames; we don't really know if a file was renamed or not, but we can\nmake a good guess.\n\n>> I think it would be easy to support this case if somehow there was a\n>> way to find all the commits that comprise a branch;\n>>\n>>  % git log branch ^<any-other-branch>\n>>\n>> I could swear I saw such an option, but I've been looking for days and\n>> I can't find it.\n>\n> I don't think there is such an option. You have to do something like:\n>\n>  {\n>    echo \"--not\"\n>    git for-each-ref --format='%(refname)' | grep -v \"^$branch\\$\"\n\nRather:\ngit for-each-ref --format='%(refname:short)' refs/heads | grep -v \"^$branch\\$\"\n\n>  } |\n>  git rev-list --stdin $branch\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"192598","messageId":"CACPiFCLUae+gyymAXr9Bdux6Mohnp4tXuS5pgNCJ9w-gjBbrwA@mail.gmail.com","threadId":"30634","inReplyTo":"20120530215415.GB3237@sigill.intra.peff.net","subject":"Re: Finding a branch point in git","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2012-05-31T15:37:48Z","receivedAt":"2012-05-31T15:37:48Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On Wed, May 30, 2012 at 5:54 PM, Jeff King <peff@peff.net> wrote:\n> >  % git log branch ^<any-other-branch>\n> >\n> > I could swear I saw such an option, but I've been looking for days and\n> > I can't find it.\n>\n> I don't think there is such an option. You have to do something like:\n\nI do\n\n   gitk olpc-kernel-branch ^origin/master\n\nto peruse OLPC's branch of the linux kernel without reading a\nbazillion commits into memory.\n\nAnyway, this whole discussion assumes a very simplistic branching and\ndevelopment scenario. Some forks and merges are due to developers\nworking offline or in per-developer repos. No automatic way to know\nwhat's an intentional branch.\n\ncheers,\n\n\n\nm\n--\n martin.langhoff@gmail.com\n martin@laptop.org -- Software Architect - OLPC\n - ask interesting questions\n - don't get distracted with shiny stuff  - working code first\n - http://wiki.laptop.org/go/User:Martinlanghoff\n"},{"id":"192600","messageId":"CAMP44s2eqLQvfaMhQJV-JmmQf3hXMK2_85OVGrd4bLqC5xzMVA@mail.gmail.com","threadId":"30634","inReplyTo":"CAMP44s1Q26B9hCdubfDiP2_YUUWGOtyyA=gSwqpGOE4FfZrN8A@mail.gmail.com","subject":"Re: Finding a branch point in git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2012-05-31T16:10:16Z","receivedAt":"2012-05-31T16:10:16Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 31, 2012 at 5:27 PM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:\n>> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:\n>>\n>>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:\n>>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:\n>>> >\n>>> >> > What about a history with multiple branches?\n>>> >> >\n>>> >> > --X--A--B--C--D----E  (master)\n>>> >> >      \\           /\n>>> >> >       G--H--I---J   (branch X)\n>>> >> >           \\    /\n>>> >> >            K--L    (branch Y)\n>>> >> [...]\n>>> >>\n>>> >> Yes, but then you would need to specify a second branch. I would avoid\n>>> >> that if possible.\n>>> >\n>>> > I agree that is less nice. But I don't think the operation is\n>>> > well-defined with a single branch. If you ask for \"when did branch X\n>>> > split\", then in the above graph it is unclear if you meant \"split from\n>>> > master\", or \"split from Y\".\n>>>\n>>> If you look from the context that I explained in the first mail; it\n>>> would be from *any* branch; IOW; find the first commit from branch X\n>>> (G), and then find the parent. That would be the first commit where\n>>> branch X started.\n>>\n>> I'm not sure that's possible, though, in the face of criss-cross merges.\n>> How do we distinguish the history above from one in which branch Y was\n>> forked from master at G, and then branch X was forked from branch Y at\n>> H?\n>\n> That is true, but we could use the algorithm used by name-rev: G would\n> have a distance 3 from branch X, and distance 2 from Y, so it would be\n> considered part of branch Y.\n\nEr, actually that would list X as branch Y. Now I believe there is a\nreal problem.\n\nHowever, I don't believe mercurial branch labels are the solution;\nprobably a pointer to the tail of the branch would provide with all\nthe information needed.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"192620","messageId":"CAJsNXTkWKP9xY-yBQF6PuF_YyGshV5xaXG-oBWAO138cFUyT1g@mail.gmail.com","threadId":"30634","inReplyTo":"CAMP44s1Q26B9hCdubfDiP2_YUUWGOtyyA=gSwqpGOE4FfZrN8A@mail.gmail.com","subject":"Re: Finding a branch point in git","fromName":"PJ Weisberg","fromEmail":"pj@irregularexpressions.net","sentAt":"2012-05-31T20:37:43Z","receivedAt":"2012-05-31T20:37:43Z","isPatch":false,"sender":{"key":"pj@irregularexpressions.net","avatar":"https://gravatar.com/avatar/aa2c1edcc61b536cc5c9f37fbce084e655446e2309f9818d43f13d47304a602b?d=mp&s=160"},"body":"On Thu, May 31, 2012 at 8:27 AM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:\n>> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:\n>>\n>>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:\n>>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:\n>>> >\n>>> >> > What about a history with multiple branches?\n>>> >> >\n>>> >> > --X--A--B--C--D----E  (master)\n>>> >> >      \\           /\n>>> >> >       G--H--I---J   (branch X)\n>>> >> >           \\    /\n>>> >> >            K--L    (branch Y)\n>>> >> [...]\n>>> >>\n>>> >> Yes, but then you would need to specify a second branch. I would avoid\n>>> >> that if possible.\n>>> >\n>>> > I agree that is less nice. But I don't think the operation is\n>>> > well-defined with a single branch. If you ask for \"when did branch X\n>>> > split\", then in the above graph it is unclear if you meant \"split from\n>>> > master\", or \"split from Y\".\n>>>\n>>> If you look from the context that I explained in the first mail; it\n>>> would be from *any* branch; IOW; find the first commit from branch X\n>>> (G), and then find the parent. That would be the first commit where\n>>> branch X started.\n>>\n>> I'm not sure that's possible, though, in the face of criss-cross merges.\n>> How do we distinguish the history above from one in which branch Y was\n>> forked from master at G, and then branch X was forked from branch Y at\n>> H?\n>\n> That is true, but we could use the algorithm used by name-rev: G would\n> have a distance 3 from branch X, and distance 2 from Y, so it would be\n> considered part of branch Y.\n>\n> Sure, it's not possible to know _for sure_, but this is a bit like\n> renames; we don't really know if a file was renamed or not, but we can\n> make a good guess.\n\nObviously G is part of branch Y, branch X, and branch master.  I'm\nsure I'm missing the whole point of this exercise, because it seems to\nme that it's just needlessly confusing to say anything else.\n\n-PJ\n\nGehm's Corollary to Clark's Law: Any technology distinguishable from\nmagic is insufficiently advanced.\n"},{"id":"192638","messageId":"CAMP44s1cETpXHMtUsq__FpFSOg9yLmh1A9uYtiTp-K6yEC4AhA@mail.gmail.com","threadId":"30634","inReplyTo":"CAJsNXTkWKP9xY-yBQF6PuF_YyGshV5xaXG-oBWAO138cFUyT1g@mail.gmail.com","subject":"Re: Finding a branch point in git","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2012-06-01T09:15:20Z","receivedAt":"2012-06-01T09:15:20Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 31, 2012 at 10:37 PM, PJ Weisberg\n<pj@irregularexpressions.net> wrote:\n> On Thu, May 31, 2012 at 8:27 AM, Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n>> On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:\n>>> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:\n>>>\n>>>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:\n>>>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:\n>>>> >\n>>>> >> > What about a history with multiple branches?\n>>>> >> >\n>>>> >> > --X--A--B--C--D----E  (master)\n>>>> >> >      \\           /\n>>>> >> >       G--H--I---J   (branch X)\n>>>> >> >           \\    /\n>>>> >> >            K--L    (branch Y)\n>>>> >> [...]\n>>>> >>\n>>>> >> Yes, but then you would need to specify a second branch. I would avoid\n>>>> >> that if possible.\n>>>> >\n>>>> > I agree that is less nice. But I don't think the operation is\n>>>> > well-defined with a single branch. If you ask for \"when did branch X\n>>>> > split\", then in the above graph it is unclear if you meant \"split from\n>>>> > master\", or \"split from Y\".\n>>>>\n>>>> If you look from the context that I explained in the first mail; it\n>>>> would be from *any* branch; IOW; find the first commit from branch X\n>>>> (G), and then find the parent. That would be the first commit where\n>>>> branch X started.\n>>>\n>>> I'm not sure that's possible, though, in the face of criss-cross merges.\n>>> How do we distinguish the history above from one in which branch Y was\n>>> forked from master at G, and then branch X was forked from branch Y at\n>>> H?\n>>\n>> That is true, but we could use the algorithm used by name-rev: G would\n>> have a distance 3 from branch X, and distance 2 from Y, so it would be\n>> considered part of branch Y.\n>>\n>> Sure, it's not possible to know _for sure_, but this is a bit like\n>> renames; we don't really know if a file was renamed or not, but we can\n>> make a good guess.\n>\n> Obviously G is part of branch Y, branch X, and branch master.  I'm\n> sure I'm missing the whole point of this exercise, because it seems to\n> me that it's just needlessly confusing to say anything else.\n\nIt's not about which commit is part of which branch, but figuring out\nwhich is the first commit that was created being in branch Y.\n\nI don't see a tremendous value on this, but there is some, for example:\n\n % git rebase --onto master branch_Y@{tail} branch_Y\n\nDepending on the case, this might not be what you want, but sometimes\nit might, the problem is that you can't know automatically if\nbranch_Y@{tail} is G, or K. So normally you would fire gitk and select\nthe commit that you want, which is not a big deal, but still, it would\nbe nice if the tail of a branch was recorded somehow.\n\nTo be clear, if I do:\n\n % git checkout -b branch_Y\n % git commit <- this would be branch_Y's tail\n\n % git rebase --onto master <- now branch_Y's tail would be right on\ntop of master\n\nCheers.\n\n-- \nFelipe Contreras\n"}]}