In the last post about git, we learned about a way to look at our commit history to get a reminder of what we had done a couple of days ago. As Philipp pointed out on Twitter, this only makes sense if you write commit messages that actually describe what the commit did instead of just saying something like bugfix, fix tests again etc. He also linked to a great blogpost describing what makes a good commit message.
Today we are going to learn how to use that knowledge to change our not so helpful commit messages to something that other people (and our future selves!) can actually work with.
There are two cases that we are going to look at: 1) You immediately realize the mistake that you have made and would like to change the last commit’s commit message. 2) You realize that you made a mistake further back in your history and would like to change it.
1) Changing your last commit’s commit message
Imagine you just fixed a difficult bug and bundled your change into a commit. Immediately afterwards you remember that your commit messages should describe what you did so you want to change the last message. In this case you can amend your commit. To do so, run
git commit --amend -m '<your new message>'. You can see this in action below:
If you pay close attention, you will notice that in the second
git log it is not only the commit message that changed but also the commit hash. This is because git wants to make sure that your commit history was not tampered with and creates hashes to based on your commits. One of the inputs for theses hashes is the commit message. Now that the hash changed, git’s representation of the most recent commit -
HEAD - is pointing to a different hash than it previously did. Whenever this happens, you will have to force push. What exactly this means, we will talk about in a later post but for now you can just remember to run
git push --force-with-lease instead of just
git push to push your changes to your remote.
2) Changing an older commit message
The previous tip only works if you realized your mistake immediately after the commit. It might also be though that you only spot your mistake later. In this case, you can use git’s interactive rebase feature.
As you can see in the recording below, this time we spotted our mistake only after we had made another commit. To fix it, we call
git rebase -i <hash>. We supply it with the commit hash of the commit before the one, that we want to change. In our case, this is the initial commit with hash
f042a53e. Once we call
git rebase -i f042a53e, we are prompted with an interactive (hence the
-i) menu that opens up in our
$EDITOR. In this menu we have to tell git, what we want to do to the commits. Our options are presented to us in the commented section in the editor:
reword, edit, squash, fixup, exec, drop. We will talk about all of those in the future, today we are going to just be using
reword though. To do so, we look at the first lines that list our commits and find the commit that we would like to change.We then change the first word (the command) to
reword. By doing that we tell git that we would like to change this commit, specifically its commit message. We save and close the file and are prompted with a regular commit message editor in which we can change the message.
If you take another close look, you will notice that once again the commit hash changed. In this case though, the hash of the commit following the one we changed (
add test for download function) also changed. This is because one of the inputs to the hash that git creates is the previous commit. This means that if any commit hash changes in the history, it will also change the hash of all of its children (sound like a blockchain, doesn’t it? 😉). You can use the same trick from above again and push with
git push --force-with-lease.
So this is how you can edit your repository’s history to be a proper logbook of the changes that you have made. Your colleagues and your future self will thank you for it. Anything I missed? Let me know on twitter.