Read Anthropic’s case study about Graphite Reviewer

Git commit message best practices

Greg Foster
Greg Foster
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


This guide details best practices for writing Git commit messages, leveraging principles from the Conventional Commits specification.

A Git commit message typically comprises three main parts: the header, the body, and the footer. The header is mandatory and includes the type of change, the scope of the change (optional), and a short description. The body is optional and provides detailed information about the change. The footer is also optional and includes additional metadata, such as related issues and breaking changes.

Header format:

Terminal
<type>(<scope>): <description>

Example:

Terminal
feat(database): add retry logic to data fetch

Conventional Commits defines several types of changes:

  • feat: Introduces a new feature.
  • fix: Patches a bug.
  • docs: Documentation-only changes.
  • style: Changes that do not affect the meaning of the code (white-space, formatting, etc).
  • refactor: A code change that neither fixes a bug nor adds a feature.
  • perf: Improves performance.
  • test: Adds missing tests or corrects existing tests.
  • chore: Changes to the build process or auxiliary tools and libraries such as documentation generation.

The scope provides additional contextual information on where the change has taken effect. For example, it might refer to a particular component or feature that the change impacts.

Example:

Terminal
fix(parser): handle unexpected end-of-file error

The description succinctly summarizes the change in a way that makes the commit message stand alone from other content. It should be imperative, stating what the commit does rather than what it did.

Bad Example:

Terminal
Fixed bug with Y

Good Example:

Terminal
Fix bug with Y

The body should include a detailed explanation of the change, including its rationale and any implications it may have. It is separated from the header by a blank line and wrapped at 72 characters to improve readability.

Example:

Terminal
fix: handle errors in the protocol
Ensure that errors close the socket and reinitialize the connection,
preventing the client from hanging in an unstable state.

The footer is used for metadata about the commit, such as related issue trackers and breaking changes. Use keywords like Fixes, Resolves, or BREAKING CHANGE: followed by a colon and a space.

Example of Breaking Change:

Terminal
BREAKING CHANGE: env vars now take precedence over config files.
  • Simple fix with description:

    Terminal
    fix: correct minor typos in code
  • Feature with scope and description:

    Terminal
    feat(parser): add support for async functions
  • Commit with multi-paragraph body and multiple footers:

    Terminal
    feat: unify exception handling
    Create a new exception handler that deals with all error cases in a unified manner. This change simplifies the control flow and makes error handling more predictable.
    Reviewed-by: Z
    Refs: #123
  • Automated Changelog Generation: Helps generate a structured changelog from commit history.
  • Semantic Versioning: Automatically determines a semantic version bump based on the types of commits.
  • Improved Collaboration: Makes it easier for team members to understand the nature of changes, facilitating quicker reviews and collaborative development.

Adhering to a standardized commit message format, like Conventional Commits, significantly benefits project management and developer communication. By clearly describing your changes with an appropriate type, scope, and detailed description, you contribute to a clear, navigable, and useful commit history.

On this page
Git inspired
Graphite's CLI and VS Code extension make working with Git effortless.
Learn more

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2