{"thread":{"id":"21460","subject":"how to rebase backwards","startedAt":"2009-11-03T05:45:10Z","lastAt":"2009-11-06T01:43:16Z","messageCount":5,"participants":["bill lam","Junio C Hamano","David Kågedal"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"126623","messageId":"20091103054510.GB7117@debian.b2j","threadId":"21460","inReplyTo":null,"subject":"how to rebase backwards","fromName":"bill lam","fromEmail":"cbill.lam@gmail.com","sentAt":"2009-11-03T05:45:10Z","receivedAt":"2009-11-03T05:45:10Z","isPatch":false,"sender":{"key":"cbill.lam@gmail.com","avatar":null},"body":"I want to rebase a new branch onto an earlier commit \n\noriginal:  \nE is a newly created branch from D and not yet modified\n                    E\n                   /\n-- A -- B -- C -- D\n\nnew: what I wanted\n     B'-- C' -- E     for deployment\n    /          \n-- A -- B -- C -- D    trunk\n\nso that I can continue to change all commits from B to C without\naffecting E\n\nI try (not sure if correct) doing it by\n  git rebase --onto A B E\n\nbut then there is a lot of conflict/both modified files. What will be\nthe correct way to do it?\n\n-- \nregards,\n====================================================\nGPG key 1024D/4434BAB3 2008-08-24\ngpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3\n"},{"id":"126631","messageId":"7vocnkt5o4.fsf@alter.siamese.dyndns.org","threadId":"21460","inReplyTo":"20091103054510.GB7117@debian.b2j","subject":"Re: how to rebase backwards","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-11-03T07:43:07Z","receivedAt":"2009-11-03T07:43:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"bill lam <cbill.lam@gmail.com> writes:\n\n> I want to rebase a new branch onto an earlier commit \n>\n> original:  \n> E is a newly created branch from D and not yet modified\n>\n>                     E\n>                    /\n> -- A -- B -- C -- D\n\nI sense a grave misconception here.  If you have \"not yet modified\"\nanything at all since D, then E does *not* even exist.\n\nRemember, a branch is just a pointer pointing at a commit.  You can have\nmore than one such pointers pointing at the same commit.  So, if you have\nbeen working on 'master' branch, building up to D, your history would look\nlike this:\n\n    ---A---B---C---D\n                   ^ master\n\nAnd you would \"create a branch\", say \"hack\", like this:\n\n    $ git checkout -b hack\n\nWhat happens to your history when you do so is this:\n\n                   v hack\n    ---A---B---C---D\n                   ^ master\n\nThe same commit \"D\", pointed by two branches, 'master' and 'hack'.\n\nIf you start editing files at this point, before making a commit, nothing\nin the history changes.  But once you make a commit E while on branch\n'hack' (since you ran \"git checkout -b hack\" above), the history changes\ninto this:\n\n                     E\n                    /^ hack\n    ---A---B---C---D\n                   ^ master\n\n> new: what I wanted\n>\n>      B'-- C' -- E     for deployment\n>     /          \n> -- A -- B -- C -- D    trunk\n>\n> so that I can continue to change all commits from B to C without\n> affecting E\n>\n> I try (not sure if correct) doing it by\n>   git rebase --onto A B E\n\nThis asks to replay C, D and E in this order on top of A, to create\n\n      C'--D'--E'\n     /\n -- A\n\nwhich is different from what you described earlier.\n\nAssuming that you did actually commit to create E, after branching 'hack'\noff of 'master', i.e. your history looks like this:\n\n                     E\n                    /^ hack\n    ---A---B---C---D\n                   ^ master\n\nthe way to create what you want would actually be\n\n    $ git checkout -b deploy master^ ;# branch deploy at \"C\"\n    $ git cherry-pick hack           ;# replay E on top of it\n\nwhich would make a history of this shape.\n\n                 v deploy\n                 E'  E\n                /   /^ hack\n    ---A---B---C---D\n                   ^ master\n\nIf you need to later tweak B and C (only) for deployment branch, you could\nfurther rewrite B and/or C with\n\n    $ git rebase -i A\n\nto rewrite everything since A leading to the tip of your current branch\n(i.e. E'), to result in\n\n                   v deploy\n           B'--C'--E\"\n          /\n         /       E'  E\n        /       /   /^ hack\n    ---A---B---C---D\n                   ^ master\n\nNow, you may not want to keep both 'hack' and 'deploy'.  Perhaps you\nforked 'deploy' and modified for E but it was done on top of D that you\ndid not want to include in 'deploy' by mistake.  IOW, you might have done\nthis:\n\n                     E\n                    /^ deploy\n    ---A---B---C---D\n                   ^ master\n\nAnother way to make 'deploy' point at the result of replaying E on top of\nC when your history looks like this is (assuming you are on 'deploy'):\n\n    $ git reset --hard HEAD^^ ;# reset to \"C\"\n    $ git cherry-pick @{1}    ;# cherry-pick \"E\"\n\nThat would give you a history of this shape:\n\n                 v deploy\n                 E'  E\n                /   /\n    ---A---B---C---D\n                   ^ master\n\nNote that the original commit \"E\" becomes dangling and it will eventually\nbe garbage-collected.\n"},{"id":"126635","messageId":"20091103093716.GD7117@debian.b2j","threadId":"21460","inReplyTo":"7vocnkt5o4.fsf@alter.siamese.dyndns.org","subject":"Re: how to rebase backwards","fromName":"bill lam","fromEmail":"cbill.lam@gmail.com","sentAt":"2009-11-03T09:37:16Z","receivedAt":"2009-11-03T09:37:16Z","isPatch":false,"sender":{"key":"cbill.lam@gmail.com","avatar":null},"body":"Thank you for detail explanation.  From what you described, I begin\nwith master commit D, \n $ git checkout -b deploy\n $ git commit --allow-empty -m deploy\n\n \n                      E\n                     /^ deploy\n     ---A---B---C---D\n                    ^ master\n \n $ git rebase -i A\n\n                      v deploy\n          B'--C'--D'--E'\n         /\n     ---A---B---C---D\n                    ^ master\n\nsince E is an empty commit, I suppose content of D' E' and D are\nidentical at this point.  Is that correct?\n\nIf several months later, I forget which is the common ancestor for\nmaster and deploy, how do I generate the above graph or identify\ncommit A as the common ancestor for these two branches?\n\n-- \nregards,\n====================================================\nGPG key 1024D/4434BAB3 2008-08-24\ngpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3\n"},{"id":"298994","messageId":"877hu4zsyq.fsf@lysator.liu.se","threadId":"21460","inReplyTo":"20091103093716.GD7117@debian.b2j","subject":"Re: how to rebase backwards","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2009-11-05T19:12:29Z","receivedAt":"2009-11-05T19:12:29Z","isPatch":false,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"bill lam <cbill.lam@gmail.com> writes:\n\n> Thank you for detail explanation.  From what you described, I begin\n> with master commit D, \n>  $ git checkout -b deploy\n>  $ git commit --allow-empty -m deploy\n\nBut why on earth would you want to use --allow-empty? There is no reason\nfor that. Just let deploy be where it is when you created it (until you\nactually add something to it).\n\n>                       E\n>                      /^ deploy\n>      ---A---B---C---D\n>                     ^ master\n>  \n>  $ git rebase -i A\n>\n>                       v deploy\n>           B'--C'--D'--E'\n>          /\n>      ---A---B---C---D\n>                     ^ master\n>\n> since E is an empty commit, I suppose content of D' E' and D are\n> identical at this point.  Is that correct?\n\nAssuming you didn't intentionally change it during rebase, yes.\n\n> If several months later, I forget which is the common ancestor for\n> master and deploy, how do I generate the above graph or identify\n> commit A as the common ancestor for these two branches?\n\nThat is exactly what git does all the time. You can use many\ncommand. For instance git log --graph master...deply whill show you both\nbranches, starting from their common ancestor. \"git merge-base deploy\nmaster\" will tell you that the common ancestor is. Etc.\n\n-- \nDavid Kågedal\n"},{"id":"126944","messageId":"20091106014316.GC3928@debian.b2j","threadId":"21460","inReplyTo":"877hu4zsyq.fsf@lysator.liu.se","subject":"Re: how to rebase backwards","fromName":"bill lam","fromEmail":"cbill.lam@gmail.com","sentAt":"2009-11-06T01:43:16Z","receivedAt":"2009-11-06T01:43:16Z","isPatch":false,"sender":{"key":"cbill.lam@gmail.com","avatar":null},"body":"On Thu, 05 Nov 2009, David Kågedal wrote:\n> command. For instance git log --graph master...deply whill show you both\n> branches, starting from their common ancestor. \"git merge-base deploy\n> master\" will tell you that the common ancestor is. Etc.\n\nDavid, thank you for this info.\n\n-- \nregards,\n====================================================\nGPG key 1024D/4434BAB3 2008-08-24\ngpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3\n"}]}