{"thread":{"id":"10013","subject":"Q: howto rebase","startedAt":"2007-09-25T14:46:59Z","lastAt":"2007-09-25T15:02:49Z","messageCount":3,"participants":["lode leroy","Johannes Schindelin","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"53999","messageId":"BAY105-F33DC84FACB8B66BFEB9EC8FFB70@phx.gbl","threadId":"10013","inReplyTo":null,"subject":"Q: howto rebase","fromName":"lode leroy","fromEmail":"lode_leroy@hotmail.com","sentAt":"2007-09-25T14:46:59Z","receivedAt":"2007-09-25T14:46:59Z","isPatch":false,"sender":{"key":"lode_leroy@hotmail.com","avatar":null},"body":"I'm trying to understand how rebase works, but I need some help to get it.\nSuppose I do the following workflow... (see below)\n\nIn \"version B\" I introduce the \"fix c\", but in \"version D\" I realize it \nshould have\nbeen in some other place. (commit D moves the fix to its proper place).\nA-B-C-D-E\n\nNow I want to 'rewrite history'.\nI would like to move commit D after B\nA-B-D'-C'-E\n\nand then fold the commits B and D' into a single commit.\nA-B'-C'-E\n\nI somehow managed to get this done using \"rebase -i\"\nby exchanging the 2 appropriate lines, and then deleting the second one,\nbut I'd like to understand how to do this from the command line...\n\nCould anyone enlighten me? I've read git-rebase(1) several times,\nbut don't seem to get it right...\n\n\ncat > file <<EOF\na\nb\nd\ne\ng\nh\nEOF\ngit add file\ngit commit -m 'A' -a\ncat > file <<EOF\na\nb\nd\ne\ng\nc\nh\nEOF\ngit commit -m 'B' -a\ncat > file <<EOF\na\nb\nd\ne\nf\ng\nc\nh\nEOF\ngit commit -m 'C' -a\ncat > file <<EOF\na\nb\nc\nd\ne\nf\ng\nh\nEOF\ngit commit -m 'D' -a\ncat > file <<EOF\na\nb\nc\nd\ne\nf\ng\nh\ni\nEOF\ngit commit -m 'E' -a\n\n_________________________________________________________________\nA lot of passions?  Collect all your personal info on one central location , \nfor free! http://get.live.com/live/features\n"},{"id":"54001","messageId":"Pine.LNX.4.64.0709251548390.28395@racer.site","threadId":"10013","inReplyTo":"BAY105-F33DC84FACB8B66BFEB9EC8FFB70@phx.gbl","subject":"Re: Q: howto rebase","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-09-25T14:49:24Z","receivedAt":"2007-09-25T14:49:24Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 25 Sep 2007, lode leroy wrote:\n\n> I'm trying to understand how rebase works, but I need some help to get it.\n> Suppose I do the following workflow... (see below)\n> \n> In \"version B\" I introduce the \"fix c\", but in \"version D\" I realize it\n> should have\n> been in some other place. (commit D moves the fix to its proper place).\n> A-B-C-D-E\n> \n> Now I want to 'rewrite history'.\n> I would like to move commit D after B\n> A-B-D'-C'-E\n> \n> and then fold the commits B and D' into a single commit.\n> A-B'-C'-E\n> \n> I somehow managed to get this done using \"rebase -i\"\n> by exchanging the 2 appropriate lines, and then deleting the second one,\n> but I'd like to understand how to do this from the command line...\n\nAlmost.  Your \"fold\" is called \"squash\".  So instead of deleting the \nsecond one, you probably wanted to squash it.\n\nHth,\nDscho\n"},{"id":"54005","messageId":"20070925150249.GA27653@coredump.intra.peff.net","threadId":"10013","inReplyTo":"BAY105-F33DC84FACB8B66BFEB9EC8FFB70@phx.gbl","subject":"Re: Q: howto rebase","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-09-25T15:02:49Z","receivedAt":"2007-09-25T15:02:49Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Sep 25, 2007 at 04:46:59PM +0200, lode leroy wrote:\n\n> In \"version B\" I introduce the \"fix c\", but in \"version D\" I realize it \n> should have\n> been in some other place. (commit D moves the fix to its proper place).\n> A-B-C-D-E\n>\n> Now I want to 'rewrite history'.\n> I would like to move commit D after B\n> A-B-D'-C'-E\n>\n> and then fold the commits B and D' into a single commit.\n> A-B'-C'-E\n>\n> I somehow managed to get this done using \"rebase -i\"\n> by exchanging the 2 appropriate lines, and then deleting the second one,\n> but I'd like to understand how to do this from the command line...\n\nThe essence of git rebase is \"move these commits as if they had happened\noff of a different base commit.\" The interactive mode of rebase is\nconsiderably more powerful, in that it allows squashing, deleting, and\narbitrary reordering. To do solve your problem without using \"rebase\n-i\", you could do this:\n\n# make a new branch based on 'B', which is where we want to base our commits\ngit-checkout -b tmp B\n# pick the changes from 'D', but don't commit\ngit-cherry-pick -n D\n# redo 'B' with the new changes\ngit-commit --amend\n\nnow you have a graph like this:\n\nA-B-C-D-E\n \\\n  \\-B' <-- branch tip\n\nso you need to rebase C-D-E on top of it (and rebase will realize that\n'D' has already been applied), with:\n\n  git-rebase --onto tmp B master\n\nConverting this to the manpage terminology, \"B\" is your upstream, and\nyou want to grab all of the changes from \"B\" to your \"master\", but you\nwant to put them on the newly created B'. Which perhaps is a little\nconfusing, but that's because git-rebase was designed for a simpler\nsituation: you and some upstream repo both made commits that the other\ndoesn't have, and you want to pretend your work is based off of their\nmost recent version.\n\nYou can see that \"rebase -i\" is a lot more flexible for these sorts of\nhistory re-writing schemes. If you really must do it without user\ninteraction, I suspect you could use a sed script as your $GIT_EDITOR.\n\n-Peff\n"}]}