threads / discuss / 10013

Q: howto rebase

Subject: Q: howto rebase

## tl;dr

3 messages between Sep 25, 2007 and Sep 25, 2007.

replies: 2people: 3as markdown or json

lode leroy· Sep 25, 2007, 14:46 UTC · lore

I'm trying to understand how rebase works, but I need some help to get it. Suppose I do the following workflow... (see below)

In "version B" I introduce the "fix c", but in "version D" I realize it should have been in some other place. (commit D moves the fix to its proper place). A-B-C-D-E

Now I want to 'rewrite history'. I would like to move commit D after B A-B-D'-C'-E

and then fold the commits B and D' into a single commit. A-B'-C'-E

I somehow managed to get this done using "rebase -i" by exchanging the 2 appropriate lines, and then deleting the second one, but I'd like to understand how to do this from the command line...

Could anyone enlighten me? I've read git-rebase(1) several times, but don't seem to get it right...

cat > file <<EOF a b d e g h EOF git add file git commit -m 'A' -a cat > file <<EOF a b d e g c h EOF git commit -m 'B' -a cat > file <<EOF a b d e f g c h EOF git commit -m 'C' -a cat > file <<EOF a b c d e f g h EOF git commit -m 'D' -a cat > file <<EOF a b c d e f g h i EOF git commit -m 'E' -a

_________________________________________________________________ A lot of passions? Collect all your personal info on one central location , for free! http://get.live.com/live/features

Johannes Schindelin· Sep 25, 2007, 14:49 UTC · re: lode leroy · lore

Re: Q: howto rebase

Hi,
On Tue, 25 Sep 2007, lode leroy wrote:
Show 18 quoted lines
> I'm trying to understand how rebase works, but I need some help to get it.
> Suppose I do the following workflow... (see below)
> 
> In "version B" I introduce the "fix c", but in "version D" I realize it
> should have
> been in some other place. (commit D moves the fix to its proper place).
> A-B-C-D-E
> 
> Now I want to 'rewrite history'.
> I would like to move commit D after B
> A-B-D'-C'-E
> 
> and then fold the commits B and D' into a single commit.
> A-B'-C'-E
> 
> I somehow managed to get this done using "rebase -i"
> by exchanging the 2 appropriate lines, and then deleting the second one,
> but I'd like to understand how to do this from the command line...

Almost. Your "fold" is called "squash". So instead of deleting the second one, you probably wanted to squash it.

Hth, Dscho

Jeff King· Sep 25, 2007, 15:02 UTC · re: lode leroy · lore

Re: Q: howto rebase

On Tue, Sep 25, 2007 at 04:46:59PM +0200, lode leroy wrote:
Show 15 quoted lines
> In "version B" I introduce the "fix c", but in "version D" I realize it 
> should have
> been in some other place. (commit D moves the fix to its proper place).
> A-B-C-D-E
>
> Now I want to 'rewrite history'.
> I would like to move commit D after B
> A-B-D'-C'-E
>
> and then fold the commits B and D' into a single commit.
> A-B'-C'-E
>
> I somehow managed to get this done using "rebase -i"
> by exchanging the 2 appropriate lines, and then deleting the second one,
> but I'd like to understand how to do this from the command line...

The essence of git rebase is "move these commits as if they had happened off of a different base commit." The interactive mode of rebase is considerably more powerful, in that it allows squashing, deleting, and arbitrary reordering. To do solve your problem without using "rebase -i", you could do this:

# make a new branch based on 'B', which is where we want to base our commits git-checkout -b tmp B # pick the changes from 'D', but don't commit git-cherry-pick -n D # redo 'B' with the new changes git-commit --amend

now you have a graph like this:
A-B-C-D-E
 \
  \-B' <-- branch tip

so you need to rebase C-D-E on top of it (and rebase will realize that 'D' has already been applied), with:

  git-rebase --onto tmp B master

Converting this to the manpage terminology, "B" is your upstream, and you want to grab all of the changes from "B" to your "master", but you want to put them on the newly created B'. Which perhaps is a little confusing, but that's because git-rebase was designed for a simpler situation: you and some upstream repo both made commits that the other doesn't have, and you want to pretend your work is based off of their most recent version.

You can see that "rebase -i" is a lot more flexible for these sorts of history re-writing schemes. If you really must do it without user interaction, I suspect you could use a sed script as your $GIT_EDITOR.

-Peff

← back to recent threads