{"thread":{"id":"6878","subject":"Rebasing a branch that contains merges","startedAt":"2007-02-19T09:12:22Z","lastAt":"2007-02-19T14:39:11Z","messageCount":4,"participants":["Andy Parkins","Junio C Hamano","A.J. Rossini"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"34986","messageId":"200702190912.24067.andyparkins@gmail.com","threadId":"6878","inReplyTo":null,"subject":"Rebasing a branch that contains merges","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-02-19T09:12:22Z","receivedAt":"2007-02-19T09:12:22Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"Hello,\n\nI've done some little experiments with rebasing a branch with merges on it.  I \nwanted to check that what I found is what is intended.\n\nI made a repository like this:\n\n * -- * -- * (master)\n      |\\\n      | A (branch1) -- M (merge)\n       \\              /\n        B (branch2) --\n\nIt's a horribly unfair thing to do, but while on merge I did\n\n git rebase master\n\nI had been hoping that both branches would rebase, but only one did.  I got:\n\n * -- * -- * (master) -- B -- M (merge)\n      |\\\n      | A (branch1)\n       \\              \n        B (branch2)\n\n\"M\" effectively now contains all of branch1's changes.  If I hadn't referenced \nthe merge head separately from the two branch heads, all the history in \nbranch1 would now be represented by \"M\".\n\nI don't think this is the right result.  Either\n * git should refuse to rebase because it would lose history\n * git should rebase both branches\n\nThe ideal result (perhaps unrealisticly) would have been\n\n * -- * -- * (master)\n           |\\\n           | A (branch1) -- M (merge)\n            \\              /\n             B (branch2) --\n\nThis is an unreasonable thing to expect a version control system to be able to \ndo - it's a nasty, complicated wish.  git is its own worst enemy for things \nlike this; it's getting to be so good at nasty unreasonable things that they \ndon't seem like fantasy-land wishes.\n\nA perfectly valid answer is \"don't be so ridiculous Andy, go away\". :-)\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIEE\nandyparkins@gmail.com\n"},{"id":"34988","messageId":"7vmz3a8p6g.fsf@assigned-by-dhcp.cox.net","threadId":"6878","inReplyTo":"200702190912.24067.andyparkins@gmail.com","subject":"Re: Rebasing a branch that contains merges","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-19T09:36:07Z","receivedAt":"2007-02-19T09:36:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Parkins <andyparkins@gmail.com> writes:\n\n> This is an unreasonable thing to expect a version control\n> system to be able to do ...\n\nI do not necessarily think so.  If you have this:\n\n       o---X\n      /\n  ---a---o---o---o\n          \\       \\ \n          -o---o---M---Y\n\nit is perfectly reasonable to want to have this:\n\n       o---X---o---o---o\n      /         \\       \\ \n  ---a           o---o---M'--Y'\n\nwhen you say \"rebase --onto X a Y\".\n\nHowever, you have to be careful.  The thing is, you do not want\nto 'rebase' a merge if the other branch came from somewhere not\nunder your control.  If 'a', 'o', 'X', 'Y' and 'M' are under\nyour control, and 'x' are from somebody else's tree in the\nfollowing picture:\n\n       o---X\n      /\n  ---a---o---o---o\n      \\           \\\n       x---x---x---M---Y\n\nand if you say \"rebase --onto X a Y\", it is not useful to rebase\n'x' when you want to rewrite your history.  They are somebody\nelse's history, and other people might have got it already, too.\nEven if you _could_ rebase them, you would rather not.\n\nAnd this is true even if 'x' are your own.  You might have\npushed out these 'x' to public repo although you haven't pushed\nout 'M', 'Y', 'o' nor 'X', and would want to rebase the\nstill-private part to clean up the history before publishing.\nIn such a case, you would want to end up with something like\nthis:\n\n       o---X---o---o---o\n      /                 \\\n  ---a           .-------M'--Y'\n      \\         /\n       x---x---x\n\nThis kind of rebase should be doable but you would need to tell\nthe tool which parents of merges you would want to rebase and\nwhich ones you do not want to touch but recreate the merge by\nmerging with your rebased branches again.  In the above 'ideal',\npicture, three 'o's have been rebased, and then merge 'M' was\nrecreated from the rebased rightmost 'o' and the rightmost 'x'\nin the original picture.\n"},{"id":"34996","messageId":"200702191048.24091.andyparkins@gmail.com","threadId":"6878","inReplyTo":"7vmz3a8p6g.fsf@assigned-by-dhcp.cox.net","subject":"Re: Rebasing a branch that contains merges","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-02-19T10:48:23Z","receivedAt":"2007-02-19T10:48:23Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Monday 2007 February 19 09:36, Junio C Hamano wrote:\n\n> > This is an unreasonable thing to expect a version control\n> > system to be able to do ...\n>\n> I do not necessarily think so.  If you have this:\n\nSorry; by \"unreasonable\", I meant \"unreasonable to expect that your VCS is \nclever enough to do it\".  It's an offhand compliment to git; I can't imagine \nany other VCS is capable of this sort of thing, so the discussion wouldn't \neven happen.\n\n> However, you have to be careful.  The thing is, you do not want\n> to 'rebase' a merge if the other branch came from somewhere not\n> under your control.  If 'a', 'o', 'X', 'Y' and 'M' are under\n> your control, and 'x' are from somebody else's tree in the\n> following picture:\n\nAbsolutely.  We can take that as a given though can't we?  That is always true \nfor a rebase, irrespective of whether its got merges in the branch.  As your \ndiagrams show, dealing with merges during a rebase just makes things more \ncomplicated in that you can now have one parent of the merge being rebasable \nand one not.\n\nMy original query should have stated my assumption: that all the merged \nbranches are mine to rebase as I see fit.\n\n> and if you say \"rebase --onto X a Y\", it is not useful to rebase\n> 'x' when you want to rewrite your history.  They are somebody\n> else's history, and other people might have got it already, too.\n> Even if you _could_ rebase them, you would rather not.\n\nCoo; this obviously makes things much harder.  What if there are further \nmerges on the merged branches?  It's going to get hard to specify which of \nthe merge branches you want to rebase and which you don't.\n\n> the tool which parents of merges you would want to rebase and\n> which ones you do not want to touch but recreate the merge by\n> merging with your rebased branches again.  In the above 'ideal',\n\nSo - rebase would need some sort of language to tell it which branch to \nfavour.\n\n $ git checkout branch-with-merges\n $ git rebase other-branch\n rebase: Aborted because commit 123456abcdef has multiple parents:\n rebase:  - 123456789abcdef\n rebase:  - abcdef123456789\n $ git rebase --include-parent abcdef123456789 other-branch\n\nYuck.  I've made myself ill now.  It's not going to be pretty is it?\n\nFor now, I wanted to make git-rebase just abort if there are merge commits in \nthe rebased branch, I had a quick look at git-rebase.sh to see if I could \nfind the place were this could be detected and have got lost.  So I've failed \nagain :-)\n\nAt the moment, git-rev-list --no-merges is used.  I don't think that, that's \nthe correct thing to do.  That just filters out the merge.  Doesn't that risk \nloss of history as I showed in my first email?\n\n\nAndy\n\n-- \nDr Andy Parkins, M Eng (hons), MIEE\nandyparkins@gmail.com\n"},{"id":"35008","messageId":"1abe3fa90702190639g3e0d6da1xa8086999ca53228@mail.gmail.com","threadId":"6878","inReplyTo":"200702191048.24091.andyparkins@gmail.com","subject":"Re: Rebasing a branch that contains merges","fromName":"A.J. Rossini","fromEmail":"blindglobe@gmail.com","sentAt":"2007-02-19T14:39:11Z","receivedAt":"2007-02-19T14:39:11Z","isPatch":false,"sender":{"key":"blindglobe@gmail.com","avatar":"https://gravatar.com/avatar/d9ce41197180da6d03ab12a6c3e9ff8a030b1677bca88ad65458c2f5566d8550?d=mp&s=160"},"body":"On 2/19/07, Andy Parkins <andyparkins@gmail.com> wrote:\n\n> So - rebase would need some sort of language to tell it which branch to\n> favour.\n\nThe more I use git, the more I start thinking that a domain-specific\nlanguage to describe merges would not be a bad thing.  It's so easy\n(painless, thought-free) to create a complex set of branches that\nyou'd like to rearrange with each other.\n\nOf course, perhaps the right solution is to be simpler and old\nfashioned and cease hyper-multitasking (i.e. shooting myself in the\nfoot).\n\n(I'm sharing Andy's assumption that my repo is just mine, not really\nshared -- add in sharing, or public use, and it gets far more complex,\nand the language idea might be a good idea, and not just an idea.\nDarcs has it's theory of patches, though it's not a language).\n\nbest,\n-tony\n\nblindglobe@gmail.com\nMuttenz, Switzerland.\n\"Commit early,commit often, and commit in a repository from which we can easily\nroll-back your mistakes\" (AJR, 4Jan05).\n"}]}