git ready

learn git one commit at a time
by Nick Quaranto

reorder commits with rebase

committed 20 Mar 2009

One of the vast uses of git rebase -i is reordering commits. Just please, PLEASE don’t rebase commits that have been pushed publicly. If you’re working with other developers, that will make the merge non fast-forwardable and creates headaches for all involved. Yes, the command allows one to rewrite history, but only do so when the commits are still on your local machine.

Now that the warnings are over, let’s get to the point. The scenario here is that you want to change up the sequence of commits. Perhaps you wanted to push certain changes farther down in history, or for some reason putting that third commit as the first one just makes more sense. So, let’s do just that. Let’s say our history looks like so:

So, let’s start by using git rebase -i HEAD~3. Your $EDITOR will pop open with some text similar to this:

pick 4c39bca gemspec tweak
pick 85409cf Version bump to 0.4.1
pick eb32194 Regenerated gemspec for version 0.4.1

# Rebase 60709da..eb32194 onto 60709da
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.

Reordering is as simple as moving the various ‘pick’ commands around. So if we wanted to swap the first commit with the last:

pick eb32194 Regenerated gemspec for version 0.4.1
pick 85409cf Version bump to 0.4.1
pick 4c39bca gemspec tweak

$ git rebase -i HEAD~3
Successfully rebased and updated refs/heads/test.

Save the file, and hopefully everything will go alright. If not, you’ll probably have a decent merge to take care of. If this gets too messy to take care of, just do a git rebase --abort and you’ll be back where you started. Don’t worry about losing data either, since you can always use the reflog to pluck out anything you might need. As expected, the history now shows the commits reversed:

Do note that the commit dates are still reversed, so it may seem a bit strange especially to others working with your repository. Reordering is probably more useful when combined with the other options available inside of interactive rebase, such as squashing or editing commit messages. If reordering commits has helped you out (or possibly hurted!) do let us know in the comments.