• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Justin Joyce

Practical tips and tutorials about software development.

  • Standing Invitation
  • Featured Posts
  • Latest
  • About

Git commit and commit message best practices

Posted Feb 19, 2023 — Updated Nov 6, 2023

I’ve seen lots of advice about git commits and messages over the years—some good, some not so good. This post will go through what works for me.

Note: I’m no git workflow expert, these are just my personal opinions developed over ~10 years working at startups.

Commit Best Practices:

  1. Commit often
  2. Try and make your commits self-contained pieces of work
  3. Try and keep your commits as small as reasonably possible

Commit Message Best Practices:

  1. Keep your messages short
  2. Make your messages as descriptive as possible while still being short
  3. Be specific

Let’s go through each point.

Git Commit Best Practices

This section is for the contents of the commits themselves—the actual code changes.

Commit Often

If you only remember one thing from this post, make it this: commit often. This has saved me countless times. I frequently commit very small changes while working—at every incremental step. I may not push the commit immediately, in fact I frequently squash commits when opening code for review, but I commit all the time. This type of history is typical:

git log

# git log doesn't normally look exactly like this, I have a custom log
6904a37  fix nil bug in summary return payload (4 hours ago) <justin>
4e47ef2  adds mapSummaryToSector method  (4 hours ago) <justin>
b972350  cleanup and lint /summaries (4 hours ago) <justin>
76a4f00  summaries endpoint functional, needs cleanup (4 hours ago) <justin>

By committing often, I always have a known working state to compare with, or to roll back to if something breaks (which it will). This also allows me to rapidly try things that might not work out; I can always just roll back to the version from 20 minutes earlier.

Keep your commits as small and self-contained as possible

This is a practice I’ve developed after many, many rebases. The smaller and more isolated each individual commit is, the easier it is to reason about the history of a branch and determine exactly what should be happening. This tip is very tightly-related to the point above about committing often; the more often you commit the smaller each commit will be.

You might see something unrelated in a file you’re working on and think “oh I should really fix that while I’m in here”, which is a great instinct, but I’d strongly recommend putting it in its own, separate commit with an associated message. You don’t want to revert a commit for adjust sidebar logo sizing and find out that it also changed behavior in your navbar.

Commit Message Best Practices

Now that we’ve gone through what goes into commits, let’s talk about the messages.

Tldr: be succinct.

Keep your messages short

If your commit message is too long to fit on one line, you should shorten it1. Chances are your messages will be viewed in someone’s terminal, or in the history on a PR in github, and no one is going to read more than the first line in either of those places2. In fact, github’s UI hides longer messages behind a button click—so you know no one is going to read them:

a long commit message in the github ui
You see that button on the right with the three dots? No one is clicking that.

There’s a lot of advice out there about messages having a short header line, and then an optional body with more detailed information, and maybe even a bulleted list of notes. I’m here to tell you no one will ever read all that. If you need that much detail in a single commit, you should either:

  1. Break that commit into multiple smaller commits
  2. Open a PR and write a detailed description

Make your messages as descriptive as possible

This might seem at odds with keeping your messages short. How can you be descriptive while also keeping it short? What if your description just has to be longer? This is why it’s important to keep your commits as small as reasonably possible, so they can be summarized succinctly. Now, “be descriptive” is a bit vague, what does “descriptive” even mean? In the context of commit messages, what I really mean is: be specific.

Be Specific

Consider the following commit message:

6904a37  adds test (4 hours ago) <justin>

Is it short? Yes. Is it descriptive? In a way, yes. Is it helpful? Not at all. The above message is useless. What test? Where? It needs to be more specific:

6904a37  adds test for rate limit backoff behavior (4 hours ago) <justin>

Ok, that’s better, and might be good enough. There likely aren’t too many places you need to worry about rate limits in your code, so this is pretty specific. However, I still think there’s room for improvement:

6904a37  test summary_client rate limit backoff behavior (4 hours ago) <justin>

Now we’re talking. I know exactly what that commit is doing.

What tense or voice should your message use?

Internet people have lots of opinions on this.

Which one of these messages is better?

fix test in summary_client
# or
fixes test in summary_client
# or
fixed test in summary_client

Answer: All three are fine. The only thing that matters is whether the message is clear, and all of these are.

I can hear the objections: “but what about consistency with auto-generated commits?” To that objection I say: who cares? Consistency within code is very important—and hopefully enforced by an automated tool—but your git history is for future-you who has to fix something you thought was clever today. All that matters to future-you is that your message is descriptive so you can figure out what happened.


Notes

  1. There’s no hard rule on the length of “one line”. Github seems to wrap at around 70 characters, so aim for less than that. ↩︎
  2. Some codebases have a mandatory, automation-triggering tag in commit messages, which takes up some space. You should still try and keep to one line, but you can always add an additional -m "[automation_tag]" on a second line. ↩︎

Filed Under: Featured, Git, Thoughts, Tips

Primary Sidebar

Recent Posts

  • Every Built-In Vim Color Scheme (with screenshots)
  • Reverse a string in Python
  • Meeting Cost Calculator
  • Vim find and replace
  • What makes an effective development team

Categories

  • Arrays (5)
  • Command Line (9)
  • Dates (3)
  • Featured (7)
  • Git (7)
  • Golang (5)
  • Javascript (8)
  • Productivity (8)
  • Projects (4)
  • Python (15)
  • Regex (2)
  • Ruby (3)
  • Shell (2)
  • Thoughts (2)
  • Tips (11)
  • Tools (3)
  • Tutorials (1)
  • Vim (4)

Archives

  • July 2024 (1)
  • February 2024 (1)
  • January 2024 (1)
  • December 2023 (1)
  • November 2023 (1)
  • October 2023 (4)
  • September 2023 (1)
  • August 2023 (2)
  • July 2023 (5)
  • June 2023 (3)
  • May 2023 (6)
  • April 2023 (5)
  • March 2023 (5)
  • February 2023 (10)
  • January 2023 (6)
  • December 2022 (7)

Copyright © 2025 · Contact me at justin [at] {this domain}

  • Privacy Policy