An opinionated guide to `git` collaboration (Part I)

Jan. 3, 2025

This is an opinionated set of git guidelines. However, I believe it is also a reasonable set of git guidelines for most teams.

This post is broken up into two parts. Part I covers git commit message standards. Part II describes usage of rebase over merge as a collaboration strategy.

In Part I, we will work through the guidelines, one-by-one, starting with simple, one-line git commit messages and working up to a full, detailed commit message with multiple paragraphs and bullet points.

Also, I would be remiss to not mention existing works that have influenced my thoughts on the subject, including OpenStack’s guidelines.

1. Start with a concise, informative, and capitalized subject line

The first line, which we’ll call the “subject line,” is a short summary (50 characters or less) of the changes made in the commit. You can think of this like the subject line of an email. My guidelines here are:

Examples:

Add user authentication feature
Rename Gear class to Cog
Reticulate splines

I, consistent with other published git guidelines, recommend 50 characters as this is the maximum visible by default in most commit log viewers and GitHub.

Why use the imperative? Both git merge and git revert use the imperative so your commits will be consistent.

Although you should aim to use the imperative throughout the commit message, comparisons between past and present implementations or behaviors should use past and present tenses.

2. Separate the subject and body with a blank line

We’ll call any line after the subject the body. If a commit requires a more detailed explanation, use a blank line to separate the subject from the body. Use complete sentences and wrap lines at 72 characters. Separate subsequent paragraphs with blank lines.

Example:

Fix bug in payment processing

There was an issue with the payment processing function that caused
incorrect calculations. This commit resolve the issue by updating the
calculation logic.

3. Use the body to explain the ‘why’ and ‘how’

The body of the commit message should explain why the changes were made and how they address the issue.

Example:

Refactor user profile update logic

The previous implementation of user profile updates was not handling
edge cases and had a high cyclomatic complexity. This commit simplifies
the logic and adds more error handling to ensure a smooth user
experience.

Cyclomatic complexity in update method was reduced from 8 to 3.

4. Use bullet points for multiple changes

If the commit includes multiple changes, you may use bullet points to clearly describe each change. This makes the commit message easier to read and understand.

Example:

Update user dashboard UI

Uses the new design guidelines and upgraded React widgets.

- Add user avatar and display name
- Improve layout of dashboard elements and use a
  hanging indent
- Update color scheme for better accessibility

5. Reference relevant issue numbers at the end of the commit body

If the commit is related to an issue in an issue tracker, include the issue number at the end of the commit message after a blank line. Choose a standard format, such as “Resolves: #123" or “Closes #123”.

Platforms like GitHub will close the associated issues when commits in a pull request include “closing” verb like “Close”, Resolve" or “Fix”. Personally, I like “resolves” as it applies generally to both enhancements and bug fixes.

Including the closing verb after the commit body provides room to list multiple resolved issues. If you list the resolved issues in the subject line you will often exceed 50 characters, especially if you’re using a non-GitHub issue tracker with long issue identifiers.

Here’s an example:

Optimize image loading for faster page rendering

Replace the current image loading library with a more efficient one,
resulting in faster page rendering times and a better user experience.

- Average time-to-load reduced from 53ms to 25ms
- Average server load reduced by 10%

Resolves: #23, #28

GitHub supports three “closing” keywords, “close,” “fix,” and “resolve,” plus their past and present tenses, e.g. “closes” and “closed.”

Here’s an example:

Add git commit guidelines

Write the subject in capitalized, concise form. Leave a blank line
after and limit the subject to 50 characters, maximum.

The first line is like an email subject. The rest is the body.
Separate the subject and body with a blank line.

- Separate paragraphs with blank lines.
- Use hyphens or asterisks for bullets.
- Hanging indents may be used with for long bullets. Here is an
  example multiline bullet

Add references to any issues resolved by this commit after the body
and separated by a blank line. Any additional commit metadata, e.g.
an external ticketing system, should be referenced

Resolves: #12, #43
Ticket: Infra#10297

Here is a good example from Brandon Willard:

Use FSM-based scanning

All the terminal symbols regexs in each parse-state-dependent lexer are
combined/unioned into a single FSM, and scanning is performed according
to those combined FSMs. The function `fsm_union` was added for that
purpose.

Since the parser needs to know exactly which terminal symbols were
matched, we now need to the ability to determine exactly which sub-FSM
(i.e. one of the combined terminal symbol FSMs) accepted an input
string. The function `get_sub_fsms_from_seq` serves this purpose.

In short, here are the guidelines:

  1. Start with a concise, informative, and capitalized subject line
  2. Separate the subject and body with a blank line
  3. Use the body to explain the ‘why’ and ‘how’
  4. Use bullet points for multiple changes
  5. Reference relevant issue numbers at the end of the commit body

Consistently following these guidelines should make it easier to understand the development of a code base over time. Additionally, these guidelines set the stage for creating a narrative in your pull or review requests such that your collaborators can easily understand your proposed changes.

(c) 2025 Dan Gerlanc