In a Git project with multiple collaborators, writing a clear commit message every time you commit code is crucial. It not only helps team members quickly understand the content of the commit but also enables tools like standard-version to automatically generate version logs later, and even saves time when troubleshooting issues. However, if commit messages are messy or non-standard—such as “fix bug” or “made some changes”—it becomes difficult to trace the purpose and impact of the changes.

Basic Format of Angular-Style Commit Specification

Angular-style commit messages are divided into three parts: Header (Title), Body (Description), and Footer (Footer). The Header is mandatory, while Body and Footer are optional. The overall structure is as follows:

<type>(<scope>?): <subject>

[body]

[footer]

1. Header (Title): Concisely Describe the Core Change

The Header format is: type(scope?): subject

  • type (Type): Must be selected from the following list to clarify the nature of the change:
  • feat: New feature
  • fix: Bug fix
  • docs: Documentation update
  • style: Formatting changes (does not affect code logic, e.g., spaces, line breaks, indentation)
  • refactor: Code refactoring (neither new feature nor bug fix)
  • perf: Performance optimization
  • test: Related to testing (adding/modifying test code)
  • chore: Other changes that do not affect code logic (e.g., build scripts, dependency management)

  • scope (Scope, Optional): Specifies the module or functional area affected by the change (e.g., login, api, home). If unclear, it can be omitted.

  • subject (Subject): Briefly describes the change. It should start with an imperative mood (e.g., “Add” instead of “Added”), be less than 50 characters, and end without a period.

Example:

feat(login): add "Remember Me" option  // Type: New feature, Scope: login module, Subject: Add "Remember Me" option

2. Body (Description): Detail the Change

The Body is used to supplement why the change was made and specific implementation details. It starts on a new line, separated from the Header by an empty line. It can span multiple lines, with each line briefly describing a key point.

Example:

feat(login): add "Remember Me" option

- Added a "Remember Me" checkbox that auto-fills account and password on the next login
- Encrypted storage is used for tokens and account information to avoid plaintext leaks

The Footer is optional and used to indicate incompatible changes (Breaking Changes) or close an Issue, also separated from the Body by an empty line.

(1) Incompatible Changes (Breaking Changes)

If the commit includes a breaking change (e.g., API modification), start the Footer with BREAKING CHANGE: to clearly describe the impact.

Example:

fix(api): correct user info response format

BREAKING CHANGE: The format of the `{name: string}` returned by the original `/api/user/profile` endpoint has changed to `{username: string}`. Old callers need to update synchronously.

(2) Close an Issue

If the commit resolves a specific issue, use the format Closes #Issue number in the Footer to link the commit to the issue.

Example:

fix(checkout): resolve payment timeout bug

Closes #123  // Closes the issue numbered 123

Complete Example Collection

Here are examples of commit messages for different scenarios:

Example 1: New Feature (feat)

feat(home): add search component

- Added a top search bar that supports real-time keyword search
- Integrated with the backend API to return matching results list

Example 2: Bug Fix (fix)

fix(auth): resolve token expiration issue

- Fixed the problem where the token was not automatically refreshed after expiration
- Added a local cache expiration time check to extend the token validity period to 7 days

Example 3: With Breaking Change

refactor(api): remove deprecated /v1/user/list endpoint

BREAKING CHANGE: The `/v1/user/list` API is deprecated. All callers must migrate to `/v2/user/list`.

Example 4: Close an Issue

docs: update contribution guide

Closes #45  // Addresses the "missing documentation" issue in #45

Tools to Assist with Commit Message Specification

Manual writing is error-prone. Here are recommended tools to automatically generate standardized commit messages:

  • Commitizen (cz-cli): An interactive command-line tool that guides you through filling in standardized information.
    Installation: npm install -g commitizen
    Usage: Run commitizen init cz-conventional-changelog --save-dev in the project root directory. Then use npm run commit instead of git commit and follow the prompts to generate a standardized message.

  • commitlint: Validates whether commit messages comply with the specification. Combine it with husky to automatically block non-standard messages before they are committed.

Notes

  1. Type must be standard: Only use the specified types (e.g., feat instead of “new”).
  2. Subject should be concise and clear: Start with a verb (e.g., “Add”, “Fix”) and avoid redundant descriptions.
  3. Body is optional but recommended for complex changes: For simple changes, the Body can be omitted, but complex logic should explain “why” the change was made.
  4. Footer must clearly mark Breaking Changes: Destructive changes must be listed separately to avoid pitfalls in subsequent development.

Summary

Standardized Git commit messages make project collaboration more efficient, helping the team quickly understand code changes and facilitating tools to automatically generate version logs. The Angular style is currently the most widely adopted specification. From your next commit, try writing commit messages in this clear format! Once you develop the habit, you’ll find troubleshooting and communication much smoother.

Xiaoye