{"thread":{"id":"27638","subject":"rewrite history","startedAt":"2011-06-16T19:17:58Z","lastAt":"2011-06-16T22:18:41Z","messageCount":9,"participants":["Ilya Basin","Jeff King","Junio C Hamano","Marc Branchaud"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"170149","messageId":"362053118.20110616231758@gmail.com","threadId":"27638","inReplyTo":null,"subject":"rewrite history","fromName":"Ilya Basin","fromEmail":"basinilya@gmail.com","sentAt":"2011-06-16T19:17:58Z","receivedAt":"2011-06-16T19:17:58Z","isPatch":false,"sender":{"key":"basinilya@gmail.com","avatar":null},"body":"Hi list. There were 2 branches. One's HEAD was modified to match a\nspecific commit at another branch. Now, how to merge them according to\nthis scheme?\n\nA---B---X---E---F\n                     =>  C---D---X---E---F\nC---D---X'\n\nX and X' have no difference. I tried to write a script to cherry-pick\nE and F, but some of commits are merges and cherry-pick fails.\n"},{"id":"170150","messageId":"20110616192644.GB13466@sigill.intra.peff.net","threadId":"27638","inReplyTo":"362053118.20110616231758@gmail.com","subject":"Re: rewrite history","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-16T19:26:44Z","receivedAt":"2011-06-16T19:26:44Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 16, 2011 at 11:17:58PM +0400, Ilya Basin wrote:\n\n> Hi list. There were 2 branches. One's HEAD was modified to match a\n> specific commit at another branch. Now, how to merge them according to\n> this scheme?\n> \n> A---B---X---E---F\n>                      =>  C---D---X---E---F\n> C---D---X'\n> \n> X and X' have no difference. I tried to write a script to cherry-pick\n> E and F, but some of commits are merges and cherry-pick fails.\n\nI think you just want to rebase using the \"-p\" option to preserve\nmerges. Something like:\n\n  $ git checkout -b rebased-branch F\n  $ git rebase -p --onto D B\n\nthat will pick X, E, and F, and replay them on top of D, resulting in\nthe graph you showed above. You could also do:\n\n  $ git rebase -p --onto X' X\n\nif you wanted to keep X' instead of X.\n\nThe new history will be stored on \"rebased-branch\". You can make sure it\nlooks good to you, and then:\n\n  $ git branch -f my_original_branch rebased-branch\n\nto move the state over to your original branch. You could also just do\nthe rebase directly on the original A-B-X-E-F branch.\n\n-Peff\n"},{"id":"170153","messageId":"7vhb7ph8aj.fsf@alter.siamese.dyndns.org","threadId":"27638","inReplyTo":"20110616192644.GB13466@sigill.intra.peff.net","subject":"Re: rewrite history","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-16T19:43:00Z","receivedAt":"2011-06-16T19:43:00Z","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> On Thu, Jun 16, 2011 at 11:17:58PM +0400, Ilya Basin wrote:\n>\n>> Hi list. There were 2 branches. One's HEAD was modified to match a\n>> specific commit at another branch. Now, how to merge them according to\n>> this scheme?\n>> \n>> A---B---X---E---F\n>>                      =>  C---D---X---E---F\n>> C---D---X'\n>> \n>> X and X' have no difference. I tried to write a script to cherry-pick\n>> E and F, but some of commits are merges and cherry-pick fails.\n>\n> I think you just want to rebase using the \"-p\" option to preserve\n> merges. Something like:\n>\n>   $ git checkout -b rebased-branch F\n>   $ git rebase -p --onto D B\n>\n> that will pick X, E, and F, and replay them on top of D, resulting in\n> the graph you showed above.\n\nEh, careful. Nobody said the change between B and X is any similar to the\nchange between D and X'. Replaying the changes E and F introduce on top of\nX' to arrive at C--D--X'-E--F is the best you could do, i.e.\n\n>   $ git rebase -p --onto X' X\n>\n> if you wanted to keep X' instead of X.\n\nis more like \"even if you wanted to keep X instead of X'\".\n\nIf you prefer commit message of X over X', you can rebase -i it after you\nare done the first round to get rid of A and B, though.\n\nBut wouldn't filter-branch a better tool for this?  Graft to pretend that\nthe parent of X is D instead of B, and filter the branch with F at its\ntip, that is.\n"},{"id":"170154","messageId":"20110616194911.GA14355@sigill.intra.peff.net","threadId":"27638","inReplyTo":"7vhb7ph8aj.fsf@alter.siamese.dyndns.org","subject":"Re: rewrite history","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-16T19:49:11Z","receivedAt":"2011-06-16T19:49:11Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 16, 2011 at 12:43:00PM -0700, Junio C Hamano wrote:\n\n> >> Hi list. There were 2 branches. One's HEAD was modified to match a\n> >> specific commit at another branch. Now, how to merge them according to\n> >> this scheme?\n> >> \n> >> A---B---X---E---F\n> >>                      =>  C---D---X---E---F\n> >> C---D---X'\n> >> \n> >> X and X' have no difference. I tried to write a script to cherry-pick\n> >> E and F, but some of commits are merges and cherry-pick fails.\n> >\n> > I think you just want to rebase using the \"-p\" option to preserve\n> > merges. Something like:\n> >\n> >   $ git checkout -b rebased-branch F\n> >   $ git rebase -p --onto D B\n> >\n> > that will pick X, E, and F, and replay them on top of D, resulting in\n> > the graph you showed above.\n> \n> Eh, careful. Nobody said the change between B and X is any similar to the\n> change between D and X'. Replaying the changes E and F introduce on top of\n> X' to arrive at C--D--X'-E--F is the best you could do, i.e.\n\nI thought that was exactly what Ilya said with \"X and X' have no\ndifference\". I assumed that meant \"they are semantically similar commits\non different bases\" (i.e., a cherry-pick) and not \"they have the exact\nsame tree state\" (i.e., \"git diff X X'\" is empty).\n\n> But wouldn't filter-branch a better tool for this?  Graft to pretend that\n> the parent of X is D instead of B, and filter the branch with F at its\n> tip, that is.\n\nIf my assumption on the meanings is reversed (i.e., X and X' really are\nthe same tree state, not introducing equivalent commits), then yeah,\nthat would be better.\n\n-Peff\n"},{"id":"170155","messageId":"17721660.20110617000644@gmail.com","threadId":"27638","inReplyTo":"20110616194911.GA14355@sigill.intra.peff.net","subject":"Re[2]: rewrite history","fromName":"Ilya Basin","fromEmail":"basinilya@gmail.com","sentAt":"2011-06-16T20:06:44Z","receivedAt":"2011-06-16T20:06:44Z","isPatch":false,"sender":{"key":"basinilya@gmail.com","avatar":null},"body":"JK> On Thu, Jun 16, 2011 at 12:43:00PM -0700, Junio C Hamano wrote:\n\n>> >> Hi list. There were 2 branches. One's HEAD was modified to match a\n>> >> specific commit at another branch. Now, how to merge them according to\n>> >> this scheme?\n>> >> \n>> >> A---B---X---E---F\n>> >>                      =>  C---D---X---E---F\n>> >> C---D---X'\n>> >> \n>> >> X and X' have no difference. I tried to write a script to cherry-pick\n>> >> E and F, but some of commits are merges and cherry-pick fails.\n>> >\n>> > I think you just want to rebase using the \"-p\" option to preserve\n>> > merges. Something like:\n>> >\n>> >   $ git checkout -b rebased-branch F\n>> >   $ git rebase -p --onto D B\n>> >\n>> > that will pick X, E, and F, and replay them on top of D, resulting in\n>> > the graph you showed above.\n>> \n>> Eh, careful. Nobody said the change between B and X is any similar to the\n>> change between D and X'. Replaying the changes E and F introduce on top of\n>> X' to arrive at C--D--X'-E--F is the best you could do, i.e.\n\nJK> I thought that was exactly what Ilya said with \"X and X' have no\nJK> difference\". I assumed that meant \"they are semantically similar commits\nJK> on different bases\" (i.e., a cherry-pick) and not \"they have the exact\nJK> same tree state\" (i.e., \"git diff X X'\" is empty).\n\n>> But wouldn't filter-branch a better tool for this?  Graft to pretend that\n>> the parent of X is D instead of B, and filter the branch with F at its\n>> tip, that is.\n\nJK> If my assumption on the meanings is reversed (i.e., X and X' really are\nJK> the same tree state, not introducing equivalent commits), then yeah,\nJK> that would be better.\n\nJK> -Peff\n\nsorry,\ngit diff X X' is empty\n\n\n-- \n"},{"id":"170156","messageId":"20110616201300.GA14674@sigill.intra.peff.net","threadId":"27638","inReplyTo":"17721660.20110617000644@gmail.com","subject":"Re: rewrite history","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-16T20:13:00Z","receivedAt":"2011-06-16T20:13:00Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jun 17, 2011 at 12:06:44AM +0400, Ilya Basin wrote:\n\n> JK> I thought that was exactly what Ilya said with \"X and X' have no\n> JK> difference\". I assumed that meant \"they are semantically similar commits\n> JK> on different bases\" (i.e., a cherry-pick) and not \"they have the exact\n> JK> same tree state\" (i.e., \"git diff X X'\" is empty).\n> [...]\n> sorry,\n> git diff X X' is empty\n\nOh, then ignore everything I said. :)\n\nI think you want to graft and filter-branch as Junio mentioned.\n\n-Peff\n"},{"id":"170165","messageId":"4DFA76B6.5030407@xiplink.com","threadId":"27638","inReplyTo":"362053118.20110616231758@gmail.com","subject":"Re: rewrite history","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2011-06-16T21:33:42Z","receivedAt":"2011-06-16T21:33:42Z","isPatch":false,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"On 11-06-16 03:17 PM, Ilya Basin wrote:\n> Hi list. There were 2 branches. One's HEAD was modified to match a\n> specific commit at another branch. Now, how to merge them according to\n> this scheme?\n> \n> A---B---X---E---F\n>                      =>  C---D---X---E---F\n> C---D---X'\n> \n> X and X' have no difference. I tried to write a script to cherry-pick\n> E and F, but some of commits are merges and cherry-pick fails.\n> \n> ...\n> \n> git diff X X' is empty\n\nIt sounds like you really want to apply X--E--F on top of D, but I don't know\nhow you can do that since you need to do *something* to D in order to get a\ntree that matches X, and that something is (presumably) *different* from the\nchange that X applied to B.  So if\n\n\tdiff B X  !=  diff D X'\n\nthen I think Junio's right that the best you can do is change the meta-data\nin X' (commit message, Author, etc) to match X then apply E and F on top of\nthat.  But filter-branch seems like overkill to me here -- I'd just use\n\"rebase -p\" but not quite as Peff described:\n\n\tgit checkout X'\n\tgit commit --amend ....   # Replaces X' with X\"\n\tgit rebase -p --onto HEAD X F\n\nGiving you\n\n\tC---D---X\"---E---F\n\nwhere\n\n\tdiff D X'  ==   diff D X\"\nand\tmeta_data(X\") == meta_data(X)\n\nBut if you're happy with C---D---X'---E---F then you can skip the \"git commit\n--amend\" step.\n\n\t\tM.\n"},{"id":"170166","messageId":"7310048292.20110617015509@gmail.com","threadId":"27638","inReplyTo":"20110616201300.GA14674@sigill.intra.peff.net","subject":"Re[2]: rewrite history","fromName":"Ilya Basin","fromEmail":"basinilya@gmail.com","sentAt":"2011-06-16T21:55:09Z","receivedAt":"2011-06-16T21:55:09Z","isPatch":false,"sender":{"key":"basinilya@gmail.com","avatar":null},"body":">> sorry,\n>> git diff X X' is empty\n\nJK> Oh, then ignore everything I said. :)\n\nJK> I think you want to graft and filter-branch as Junio mentioned.\n\nJK> -Peff\n\nI'm puzzled. How to undo an unfortunate attempt of filter-branch?\ngit log origin/master returns irrelevant info, although I didn't push\nit to origin and I also tried git branch -D master, -rD master and git\nfetch -f\n\n\n-- \n"},{"id":"170169","messageId":"724671388.20110617021841@gmail.com","threadId":"27638","inReplyTo":"7310048292.20110617015509@gmail.com","subject":"Re[3]: rewrite history","fromName":"Ilya Basin","fromEmail":"basinilya@gmail.com","sentAt":"2011-06-16T22:18:41Z","receivedAt":"2011-06-16T22:18:41Z","isPatch":false,"sender":{"key":"basinilya@gmail.com","avatar":null},"body":">>> sorry,\n>>> git diff X X' is empty\n\nJK>> Oh, then ignore everything I said. :)\n\nJK>> I think you want to graft and filter-branch as Junio mentioned.\n\nJK>> -Peff\n\nIB> I'm puzzled. How to undo an unfortunate attempt of filter-branch?\nIB> git log origin/master returns irrelevant info, although I didn't push\nIB> it to origin and I also tried git branch -D master, -rD master and git\nIB> fetch -f\nNevermind, forgot to rm .git/info/grafts\n\n\n-- \n"}]}