Git Tip of the Day – rebasing is fun

Rebasing means re-ordering the commits in history. It always changes history. It means rebasing is good for your local branches, but not for branches that many people work on. Because in that case changed history means a lot of annoyed programmers.

Rebasing feature branch to master

The most common use-case is probably with feature branches. You split your feature branch from master. You develop a feature, appending a few commits. Now, you would like to send a patch to the project. But in the meantime the master branch moved. Project developers politely ask you to send the patch based on the current master. What to do? Rebase against master.

$ git checkout feature
$ git rebase master

This will find the common ancestor of feature and master (the split point). Then it will apply all changes from master. And then it will apply all changes you have done on feature since the split point. See the images.

Your code will then seem as if you based it on the current master. You can then do a simple patch git diff master feature and send it.

Rebasing a single branch

Rebasing can also be used on a single branch. It can re-order the commits in history, delete some commits, squash some commits, and more.

Let’s say I have realized I would like to have my last three commits in the feature branch in a different order:

$ git rebase --interactive HEAD~3
pick bb6f59e Update minimum python version requirement to 2.6 in the spec file.
pick 4e929b8 Improve docs in autoqa package.
pick 7796850 changed NEWS

# Rebase d03c059..7796850 onto d03c059
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

HEAD~3 denotes the fourth most recent commit. That is the base, the last commit that stays intact. It opens an editor with the last three commits in their commit order, most recent being last. You can now easily change commit order by re-ordering the lines. You can also delete commit by deleting the line.

If you change the keyword in the first column, you can edit commit, reword it, squash several commits into one, and many more. Play with it, it’s fun. If you choose to edit some commit, the rebasing process will stop at that point and allow you to do the changes. After you’re done, just execute git rebase --continue to continue with the process. If git find some conflict it can’t solve, it will again stop, you resolve the conflict and use the same command for continuing. You can abort the whole process anytime, if you wish, by issuing git rebase --abort.

Of course, always back-up your code by keeping a back-up branch before performing a difficult rebase process.

Enjoy!

Flattr this

Advertisements
Git Tip of the Day – rebasing is fun

2 thoughts on “Git Tip of the Day – rebasing is fun

  1. One more note: I just learned that ‘git rebase’ (or ‘git apply’) can also automatically fix whitespace errors for you: ‘git rebase –whitespace=fix BASE’. Neat. Of course the usual warning about changing commit checksums applies.

  2. Jason Merrill says:

    There’s no need to make a back-up branch. If you run into problems you can just git reset ORIG_HEAD, or if that’s wrong for some reason use git reflog to find the old head.

Leave a Reply (Markdown syntax supported)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s