Last Updated: February 25, 2016
·
581
· brianriley

Fix your commits

The other morning I was going through a bunch of changes and splitting them up into multiple commits. After a few commits, I saw a file changed that I should have included two commits back. You can do a git commit --amend to add your staged change to the previous commit, but adding this to a commit further back in the history is a little more involved.

But not impossible. git rebase -i is a tool you can use, for better or for worse, to do all sorts of history manipulation. Here's how you can use it to amend a commit two commits back.

So again, the situation is that you have two commits and a change (to file1b) that should have gone into the first commit.

$ git log --oneline
93c0d5c change to file2
9703cef change to file1a

The first thing to do is to commit your change.

$ git add file1b
$ git commit -m "forgot to add this 2 commits ago"
$ git log --oneline
1a48423 forgot to add this 2 commits ago
93c0d5c change to file2
9703cef change to file1a

Now start the interactive rebase selecting the commit from which to start manipulating. Here, we're starting from three commits prior.

$ git rebase -i HEAD~3

You'll be dropped into your $EDITOR and see something like this:

pick 9703cef change to file1a
pick 93c0d5c change to file2
pick 1a48423 forgot to add this 2 commits ago

Change it to look like this:

pick 9703cef change to file1a
squash 1a48423 forgot to add this 2 commits ago
pick 93c0d5c change to file2

(Move the forgotten commit just after the commit it should be added two, and change "pick" to "squash.")

When you save and exit, git will bring you back into your $EDITOR and ask you to edit your commit message:

# This is a combination of 2 commits.
# The first commit's message is:

change to file1a

# This is the 2nd commit message:

forgot to add this 2 commits ago

In this particular example, I might get rid of the "forgot..." message all together and change the "change to file1a" message. Save and exit, and git will squash commit 1a48423 into 9703cef--making them one commit.

With the interactive rebase, git lets you alter the past in ways that can be really dangerous. And you really shouldn't be doing it on commits already pushed to a remote. But this is one case where I think it's incredibly valuable.

Further reading

Rewriting History