{"thread":{"id":"27967","subject":"Automatically identifying the \"split\" point of a merged branch.","startedAt":"2011-07-31T00:54:59Z","lastAt":"2011-07-31T06:08:25Z","messageCount":3,"participants":["Conrad Irwin","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"172420","messageId":"CAOTq_ptov+6ixvyVvK3iuDp4L-=9PtKES14O93kL9n6hUz0JHA@mail.gmail.com","threadId":"27967","inReplyTo":null,"subject":"Automatically identifying the \"split\" point of a merged branch.","fromName":"Conrad Irwin","fromEmail":"conrad.irwin@gmail.com","sentAt":"2011-07-31T00:54:59Z","receivedAt":"2011-07-31T00:54:59Z","isPatch":false,"sender":{"key":"conrad.irwin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/94272?v=4"},"body":"Hello Gitters,\n\nI wonder if I might pick your brains on the best way to handle a\nsituation I found myself in recently:\n\nWe have an integration branch, and a master branch, and a topic branch\nthat was based on the integration branch. Graphically:\n\nA-o-o-o-o-o-o-o-o-o-E-(master)\n \\\n  o-o-B-o-o-o-o-M-o-o(integration)\n       \\       /\n        C-o-o-D (topic)\n\nI wanted to introduce this branch onto master to end up with:\n\nA-o-o-o-o-o-o-o-o-o-E-----------N (master)\n \\                   \\         /\n  \\                   C'-o-o-D' (topic-rebased)\n   \\\n    o-o-B-o-o-o-o-M-o-o(integration)\n         \\       /\n          C-o-o-D (topic)\n\n(ASCII art reproduced at http://dpaste.org/GUmM/ lest it be munged)\n\nWhile it's easy to create comit N once I have commit D' (with git\nmerge --no-ff), I found that it's not at all easy to work out where\ncommit B is in order to do do a rebase --onto master B.\n\nMy usual approach would be to try and use git merge-base, but because\nthe topic branch is already merged into the integration branch, that\ndoesn't give useful output.\n\nIs there a good way around this?\n\nConrad\n"},{"id":"172421","messageId":"20110731055310.GA14384@sigill.intra.peff.net","threadId":"27967","inReplyTo":"CAOTq_ptov+6ixvyVvK3iuDp4L-=9PtKES14O93kL9n6hUz0JHA@mail.gmail.com","subject":"Re: Automatically identifying the \"split\" point of a merged branch.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-07-31T05:53:10Z","receivedAt":"2011-07-31T05:53:10Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jul 30, 2011 at 05:54:59PM -0700, Conrad Irwin wrote:\n\n> I wanted to introduce this branch onto master to end up with:\n> \n> A-o-o-o-o-o-o-o-o-o-E-----------N (master)\n>  \\                   \\         /\n>   \\                   C'-o-o-D' (topic-rebased)\n>    \\\n>     o-o-B-o-o-o-o-M-o-o(integration)\n>          \\       /\n>           C-o-o-D (topic)\n> \n> (ASCII art reproduced at http://dpaste.org/GUmM/ lest it be munged)\n> \n> While it's easy to create comit N once I have commit D' (with git\n> merge --no-ff), I found that it's not at all easy to work out where\n> commit B is in order to do do a rebase --onto master B.\n\nIf you know M, then B is the merge-base of M^1 and M^2 (i.e., the\nparents of M). If you don't know M, but do know D, you can find it by\nwalking backwards from \"integration\" until you find a merge commit with\nD as its second parent (e.g., by grepping \"rev-list --parents\").\n\nMake sense?\n\n-Peff\n"},{"id":"172422","messageId":"CAOTq_psXsjipBxcG+86bQvPwQj866iAf_c9nQJ=KvjCjYHtySg@mail.gmail.com","threadId":"27967","inReplyTo":"20110731055310.GA14384@sigill.intra.peff.net","subject":"Re: Automatically identifying the \"split\" point of a merged branch.","fromName":"Conrad Irwin","fromEmail":"conrad.irwin@gmail.com","sentAt":"2011-07-31T06:08:25Z","receivedAt":"2011-07-31T06:08:25Z","isPatch":false,"sender":{"key":"conrad.irwin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/94272?v=4"},"body":"On Sat, Jul 30, 2011 at 10:53 PM, Jeff King <peff@peff.net> wrote:\n> On Sat, Jul 30, 2011 at 05:54:59PM -0700, Conrad Irwin wrote:\n>\n> If you know M, then B is the merge-base of M^1 and M^2 (i.e., the\n> parents of M). If you don't know M, but do know D, you can find it by\n> walking backwards from \"integration\" until you find a merge commit with\n> D as its second parent (e.g., by grepping \"rev-list --parents\").\n>\n> Make sense?\n\nYup. git rev-list was definitely the tool I was missing, thank you :).\n\nConrad\n\nmerge=$(git rev-list --parents integration |\\\n                 grep \" $(git rev-parse topic)\" | cut -d' ' -f 1)\nsplit=$(git merge-base $merge^ $merge^2)\ngit rebase --onto master $split\ngit checkout master\ngit merge --no-ff topic\n"}]}