Recently I ran into an instance where I accidentally added the same "Initial commit" message to a repository twice after I had forgotten that I had selected the "Initialize this repository with a README" option on GitHub. Normally I would just pop the second commit off of the HEAD using
git reset HEAD^, but I didn't realize the issue until many commits later. Once I found that issue I knew that I had to figure out how to fix my problem, as well as update some of my commit messages that were in the past tense, which goes against my preferred style.
Interactive Git Rebase to the Rescue!
The interactive git rebase command gives you the ability to alter individual commits as you move commits to a new base. Essentially
git rebase -i allows you rewrite a the git commit history of a repository interactively in an editor. That command will provide you with information about what commands are available while rebasing that include things like squashing commits together, rewording commits, and splitting commits up. This specific example isn't going to go into too much depth on how to use all of the commands.
Instead I'm going to go into an example on how to do an interactive rebase of the first two commits of a repository, as well as the rewording of a commit message. When rebasing always be careful, as it is altering the commit history of a repository, which can have significant implications.
Combine First Two Commits and Edit Another Commit Message
Here's the git log for my example, which I obtained using the
git log --oneline command. In this repository I've accidentally created two commits with the same message of "Initial commit". There's also a message that's in the past tense that I want to change change to the present tense. Note I have it configured such that my interactive git sessions open up in my editor, which in this case is Sublime.
Initially I thought that I could use the SHA of the first commit like this
git rebase -i 3f564ee, but that gave me the following result, which didn't contain both of the "Initial commit" messages.
After that I did a little bit of research and discovered that the SHA you are providing to the
git rebase -i command is actually the parent of the commit you want to work on, not the actual commit you will be editing. A little bit more reading found that instead of using the SHA of the first commit, that I needed to use the
--root option instead. With that new information the updated command is now
git rebase -i --root, which resulted in the following options in Sublime.
The commit history is listed from oldest at the top, to newest at the bottom. Now that I have access to all of the commits in my repository, I want to squash the second initial commit message, SHA
04c9c27, into the previous commit. Additionally I want to reword the commit message for the commit with SHA
ef39064. The interactive rebase provides the list of commands that are available, as can be seen on lines 9-14 in the image above. In this case I updated the file to look like the following image.
After doing this I saved the file and closed it, after which the following came up.
Next I was able to edit the commit messages to keep the one that I wanted, which admittedly in this case is the same message.
After I saved and closed the previous editor window the interactive rebase to reword the commit came up as seen below.
I then edited the commit message to be what I wanted, as seen below.
Finally I saved and closed the interactive git editor and the rebase was complete! The final git log output can be seen below with only one "Initial commit" message and the the other one updated to my desired wording.
Take advantage of git rebase, but be mindful
git rebase be mindful if you are working on a project with other people. If you alter the commit history you can create a lot of merge conflicts and even other issues with your teammates. I'd also recommend making sure that when you're using
git rebase that you have remote copy of your repository, that way you can always go back to that copy. There are many other uses to
git rebase that aren't covered here. Let me know about some of your favorite uses!