Amending Git Commits

Amending Git Commits

A best practice when using version control like git, is that commits should be small and relate to one aspect of your codebase. For example, a commit should include a correction for one function, in one part of your app, and not an update to a function, a new fetch request, and documentation changes. Think about it this way. If you had to revert or correct a change in a commit that touched many files or many aspects of a project, it would take more work and increase the likelihood of errors.

Similar to writing functions with a single responsibility, your commits and commit messages should equally concise.

While making some updates to a project of mine, I made the mistake of lumping two groups of code changes into one commit. Since this is a personal project, that likely I will only work on, it's not the end of the world. However, I try to follow best practices whenever I can. Previously, if I lumped to much code into one commit. I'd make a new commit, reverting the changes (or, what changes I could remember 😬). Then, make a new commit, with part one of the changes I made the first time. Then another commit with part two of the changes.

This is messy and again, creates room for error.

Fortunately, there is an easier way.

git commit --amend

With the command git commit --amend you can do two things.

  1. Update the message associated with the most recent commit
  2. Update the content associated with the most recent commit

I'll walk through how to do the latter, although the steps are similar.

Note. Your terminal set up or exact commands may look different, depending your your computer set up. I use a Mac OS, Bash Terminal and either Atom or Visual Studio Code for editing files.

Oops! Too much code.

In my scenario, I was making some updates to the CSS of my person website. I replaced any hard coded hex values with CSS variables and adding some smooth scrolling behavior. Here's a simplified version of my "oops" commit with too many code changes.

:root {
  --primary-color: #981ceb;
  --secondary-color: #111111;
}

html {
  scroll-behavior: smooth;
}

a, a:visited, a:hover, a:active {
  border-bottom: 1px solid var(--primary-color);
  color: var(--primary-color);
  text-decoration: none;
}

...

That scroll-behavior attribute shouldn't be there! But it's ok, we can amend this commit, get rid of that extra code and keep our commit history nice and clean.

Updating the Commit

First, in the same branch as the "oops" commit, make your changes. In my case, I'll remove the scroll-behavior line. My CSS file now looks like this.

:root {
  --primary-color: #981ceb;
  --secondary-color: #111111;
}

a, a:visited, a:hover, a:active {
  border-bottom: 1px solid var(--primary-color);
  color: var(--primary-color);
  text-decoration: none;
}

...

At this step, you can also add code (or files) that you forgot to add to the previous commit.

Next, in your terminal, run git commit --amend which will drop you into the commit editor.

If you haven't seen it before, there can be a lot going on. Mine looked something like this.

Oops - This commit has too much code in it.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sat Aug 15 00:02:16 2020 -0400
#
# On branch master
# Changes to be committed:
#       modified:   styles.css
#

If you want to keep the commit message the same, hit esc then type :wq to exit the editor and go back to your terminal.

That's it!

If you type git log you will see your commits, with the most recent one—the one you just corrected—on top.

Time Travel is Tough

This is the very top of the iceberg of what rewriting history in git can look like. Always proceed with caution, especially in a larger project that other developers may be working on, forking, etc.

Resources