·

Best Practices for Writing Commit Messages with Conventional Commits

Best Practices for Writing Commit Messages with Conventional Commits

Imagine navigating a large codebase and encountering a commit history filled with vague messages like "fix stuff" or "update code." It's a frustrating and unhelpful experience.

This usually happens due to the lack of a structured way to write commit messages within a project or a team. A better approach is to use a standardized specification, preferably an opinionated method, that provides a clear and consistent format for commit messages. This not only enhances clarity but also enables workflow automation. Enter conventional commits.

Conventional Commits

The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history.

The format is straightforward:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)] 

Type

Types of commits include:

  • build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
  • ci: Changes to your CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
  • docs: Documentation only changes
  • feat: A new feature
  • fix: A bug fix
  • perf: A code change that improves performance
  • refactor: A code change that neither fixes a bug nor adds a feature
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.)
  • test: Adding missing tests or correcting existing tests
  • revert: reverts a change

Example:

feat: add OAuth2 login support

Types can be found in configurations like @commitlint/config-conventional based on the (Angular convention).

Scope (optional)

A scope may be provided to a commit’s type, to provide additional contextual information and is contained within parenthesis.

Example:

feat(auth): add OAuth2 login support

Body (optional)

A commit body is free-form and MAY consist of any number of newline separated paragraphs.

Example:

feat(auth): add OAuth2 login support

Implemented OAuth2 login functionality for Google and GitHub, including new routes for OAuth2 callback handling and token exchange.

One or more footers MAY be provided one blank line after the body. Each footer MUST consist of a word token, followed by either a :<space> or <space># separator, followed by a string value (this is inspired by the git trailer convention).

Footers can include:

  • BREAKING CHANGE: Description of a change that breaks backward compatibility.
  • References: Links or issue numbers related to the commit.

Example:

feat(auth): add OAuth2 login support

Implemented OAuth2 login functionality for Google and GitHub, including new routes for OAuth2 callback handling and token exchange.

BREAKING CHANGE: The login API has changed to support OAuth2

Closes #456

More examples here.

Reverts

Conventional Commits does not make an explicit effort to define revert behavior.

One recommendation is to use the revert type, and a footer that references the commit SHAs that are being reverted:

revert: undo the great pizza disaster of '23

Refs: 8b5c8f0, 9a2f8d7

Benefits

Clarity and Consistency

  • Before: "fix bug"
  • After: fix(auth): resolve logout issue by resetting session data

The latter provides clear information on what was fixed and where, making it easier for anyone reviewing the commit history to understand the changes.

Automated Tools

  • Tools can automatically generate changelogs based on commit messages.
  • Helps in versioning your software with Semantic Versioning.

Example: From the above commits, an automated tool can generate a changelog entry like:

  • New Features:
    • Add user login functionality
  • Bug Fixes:
    • Resolve logout issue by resetting session data
  • Breaking Changes:
    • The login API has changed to support OAuth2.

Better Collaboration

This practice allows your team to quickly grasp the context of each change. New team members can also get up to speed faster, as the commit history provides a clear and concise record of changes.

Improved Code Quality

Conventional Commits encourage thoughtful, meaningful commits, promoting a more disciplined approach to version control.

How to Adopt Conventional Commits

  1. Start Simple: Begin by following the format manually.
  2. Use Tools: Tools like commitlint can help enforce the specification and make it easier to write proper commit messages.
  3. Educate Your Team: Share the benefits and encourage your team to adopt the practice.

For more details and a a full list of examples, visit the Conventional Commits website.


As a strong advocate for coding standards and best practices, I believe that adhering to these guidelines significantly improves productivity, streamlines team collaboration, and simplifies the onboarding process. By following established conventions and workflows, we can ensure a more efficient and cohesive development environment.