Git Commit Message Sucks

As you begin creating commits you might ‘accidentally’ create a commit message that is borderline atrocious; something like ‘Fixed the thing’. Although you are definitely aware of the thing you just fixed, other collaborators (including future you) will not know what you fixed and more importantly, why you needed to fix it. Thankfully, Git is well aware of our tendency to craft terrible commit messages and has a handful of commands that save even the vaguest commit message.

Keep in mind, all exercises expect you to have run the script to create files using the scripts found on the Set Up Your Environment page.

I didn't push

You have a couple of options when it comes to fixing a bad commit message. First, you need to ask yourself:

Am I trying to fix the last commit I made or one a few commits back?

Fixing the Last Commit

If you are fixing the last commit you made you can do the following:

  1. Ensure you are on the correct branch
  2. Use git log --oneline to ensure the commit you want to fix is at the top of the list.
  3. Enter: git commit --amend.
  4. Enter the desired commit message and close the text editor.

BOOM you just fixed your terrible commit message and now no one is the wiser. Congratulations!!!

Fixing an Older Commit

If you aren’t fixing your last commit, you can perform the following:

  1. Ensure you are on the correct branch and enter: git log --oneline
  2. Identify the SHA-1 hash associated with the commit just before the one you want to fix. For practice, let’s use the one where file 4 was added.
  3. Enter git reset --mixed SHA-1, where SHA-1 is the SHA-1 of the commit before the one you want to fix.
  4. The changes you made in the file 5 and file 6 commits are now sitting in your working directory. Simply re-add and re-commit the changes.
I pushed

Before you begin worrying about that terrible commit message you have pushed to the remote, let’s talk about the risks associated with fixing it. Fixing a commit message you have already pushed is going to require you to use git push --force-with-lease. Using push --force-with-lease can cause some serious problems for other collaborators on your project. The embarrassment of a mispelled :grin: word is nothing compared to the embarrassment of messing up your collaborators. If your commit is really that bad, or if causing problems doesn’t trouble you, keep reading.

Start by asking yourself:

Am I trying to fix the last commit I made or one a few commits back?

Fixing the Last Commit

If you are fixing the last commit you made you can do the following:

  1. Ensure you are on the correct branch
  2. Use git log --oneline to ensure the commit you want to fix is at the top of the list.
  3. Enter: git commit --amend.
  4. Enter the desired commit message and close the text editor.
  5. Enter: git push --force-with-lease to force your change to your remote.

BOOM you just fixed your terrible commit message and you potentially caused problems for other collaborators. Congratulations!!! In all seriousness, editing a commit message might seem important at the time, but pushing a terrible commit message isn’t the worst thing in the world, so it is recommended that you do this sparingly.

Fixing an Older Commit

If you aren’t fixing your last commit, you can perform the following…actually wait, this process is very complex and you really need to figure out if you need to fix those commit messages that badly.

Still here? Ok, here we go:

  1. Ensure you are on the correct branch and enter: git log --oneline
  2. Identify the SHA-1 hash for the commit just before the one you would like to change. For this example, let’s pretend we want to fix the commit for file 5, so we will pick the SHA-1 associated with the file 4 commit.
  3. Enter: git rebase -i SHA-1, where SHA-1 is the SHA-1 of the commit for adding file 4. The -i is the interactive option and will open your text editor, allowing you to modify the rebase script.
  4. Identify the commits you want to modify in the list and replace the word pick with an e or the word edit. When you are happy with your selections, close the editor and go back to the terminal.
  5. The rebase will stop at the first commit to be edited. To begin editing the first commit message, enter git commit --amend. Your text editor will open, allowing you to edit the commit message.
  6. Close the text editor and enter: git rebase --continue.
  7. Repeat the two previous steps for each commit you would like to edit.
  8. When you have edited the last commit, the rebase will finish. Enter: git push --force-with-lease to push your new commits to the remote.
Tell me why

Commit –amend

The commit --amend command enables you to modify the message and contents of the last commit you made.

This can be helpful if you identify a spelling error or grammatical issue with the commit message you created or if you forgot to add some of the changes in the working directory.

How commit –amend Works

git commit --amend will combine the changes in your staging area with the changes in the last commit you made. Your text editor will also open, allowing you to edit the commit message.

Push –force-with-lease

The push --force command allows you to override a branch history. This can be problematic if another collaborator pushed some commits to the branch you are working on. If you forgot to fetch the latest updates before pushing with the --force flag, those commits will be deleted.

On the other hand, the less known --force-with-lease flag checks if you have fetched the latest updates before you decide to rewrite history, avoiding problematic situations. If there are updates to the branch you are working on, and you didn’t fetch them, the --force-with-lease will make the push command fail.

Reset

For more information on git reset, check out the ‘Tell me why’ section in the Too Many (small) Commits scenario.

Rebase

The git rebase command is a powerful tool that can be used to reorder commits, edit commits, or even pick up entire branches and move them.

How Rebase Works

Let’s start with a fairly common use case for rebase:

Image of two branches with commits, one branch points to a parent commit 4 from the most recent commit on master set up for recursive merge

In the above image, we created a branch called test and did some work. The branch test is “based” on the first commit on master: e137e. While we were working on our test branch, some of our collaborators merged their work into master. If we want to merge in our test branch, git would need to recursively combine the history on the two branches. This recursive merge strategy would result in a new commit being made as you see below:

Image of same two branches but with new merge commit after recursive merge

Alternatively, you can use rebase to move the “base” of your test branch to the current tip of master:

Image of same branches, but if the feature branch had been rebased onto master instead of merged

As you can see from the diagram, git picked up the commits on our original test branch a55e, 97d6 and 1c70 and replayed the entire branch as if we had just created it from master. However, you should also notice the commits that occurred on the test branch have new SHA-1 hashes because the “base” commit for the branch has changed.

If we were to merge these two branches now, git would do a fast-forward merge, giving us a nice linear history (without the recursive merge commit).

Rebase Interactive

Rebase includes an interactive option that allows us to make changes to the commits as they are being replayed. For example, we can edit our commit messages as well as combine (squash), re-order, and even delete commits.

Stuck? Open an issue in the repository for this class and mention @githubteacher for help from one of the GitHub trainers!
Continue