DEV Community

Raj Beemi
Raj Beemi

Posted on

Mastering Git Commit Messages: The Conventional Commits Approach

As developers, we spend a significant amount of time writing code. But how much thought do we put into our commit messages? Good commit messages are crucial for maintaining a clean and understandable Git history. Enter Conventional Commits, a specification for adding human and machine-readable meaning to commit messages.

Why Conventional Commits?

  1. Automatic versioning: Tools can automatically determine the next semantic version based on the types of commits.
  2. Automatic changelog generation: With structured commit messages, generating changelogs becomes a breeze.
  3. Easier to understand: Team members can quickly grasp the nature of changes without diving into the code.
  4. Better organization: Commits are naturally categorized, making it easier to navigate project history.

The Structure

A conventional commit message has the following structure:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
Enter fullscreen mode Exit fullscreen mode

Let's break this down:

Types

The type field describes the nature of the change. Common types include:

  • feat: A new feature
  • fix: A bug fix
  • 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: A code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to our CI configuration files and scripts

Scope

The scope is optional and provides additional contextual information. For example:

feat(auth): add login functionality
Enter fullscreen mode Exit fullscreen mode

Here, auth is the scope, indicating that this feature is related to authentication.

Description

The description is a short summary of the code changes. It should be written in the imperative mood, as if you're giving a command. For example:

  • "add login functionality" (not "added" or "adding")
  • "fix race condition in data processing" (not "fixed" or "fixing")

Body

The body is optional and can be used to provide more detailed explanatory text. It should be separated from the description by a blank line.

Footer

The footer is optional and is used to reference issue tracker IDs or provide additional metadata.

Examples

Let's look at some examples of conventional commit messages:

feat: add user registration functionality

Implement a new user registration form and backend logic to create new user accounts.

Closes #123
Enter fullscreen mode Exit fullscreen mode
fix(database): resolve connection timeout issue

Increase database connection timeout from 5s to 15s to account for network latency.

This change should reduce the number of failed database connections during peak hours.
Enter fullscreen mode Exit fullscreen mode
docs: update README with new build instructions

- Add section on environment setup
- Update outdated CLI commands
- Include troubleshooting tips
Enter fullscreen mode Exit fullscreen mode
refactor!: change API endpoint structure

BREAKING CHANGE: The API endpoint structure has been completely revamped. 
Clients will need to update their API calls to match the new structure.

Old structure: /api/v1/users/get
New structure: /api/v2/users
Enter fullscreen mode Exit fullscreen mode

Note the use of ! and BREAKING CHANGE: in the last example. This indicates a breaking change, which is crucial for semantic versioning.

Implementing in Your Workflow

  1. Team Agreement: Discuss and agree on the commit convention with your team.

  2. Git Hooks: Use tools like Husky to set up Git hooks that validate commit messages.

  3. IDE Integration: Many IDEs have plugins that support conventional commits. For example, VS Code has the "Conventional Commits" extension.

  4. Commit CLI: Use tools like commitizen to guide you through writing conventional commits:

   npm install -g commitizen
   commitizen init cz-conventional-changelog --save-dev --save-exact
Enter fullscreen mode Exit fullscreen mode

Then, use git cz instead of git commit to commit your changes.

  1. Automation: Set up tools to automate versioning and changelog generation based on your commits.

Benefits in Action

Let's see how these structured commits can be used:

  1. Generating Changelogs: Tools like standard-version can automatically generate changelogs:
   npx standard-version
Enter fullscreen mode Exit fullscreen mode
  1. Filtering Commits: You can easily filter commits by type:
   git log --oneline --grep "^feat"
Enter fullscreen mode Exit fullscreen mode
  1. Semantic Versioning: Tools can determine the next version based on commit types. For example, a fix might bump the patch version, while a feat bumps the minor version.

Conclusion

Adopting conventional commits might seem like a small change, but it can significantly improve your project's maintainability and collaboration efficiency. By providing a clear structure for commit messages, you're not just documenting changes – you're building a roadmap of your project's evolution.

Remember, the goal is clear communication. While following the convention is important, the most crucial aspect is conveying the essence of your changes effectively to your team and your future self.

Have you used conventional commits in your projects? What has been your experience? Share your thoughts and tips in the comments below!

git #programming #bestpractices #productivity #teamwork

Top comments (0)