The Tao of Git Commit: Standardized Commit Message Writing Guide

1 commit message specification

The commit message format includes three parts: Header, Body and Footer

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

<body>

<footer>

Header is required, Body and Footer can be omitted.

1.1 Header

  1. Type (required)

    type is used to describe the category of git commit, and the following identifiers are allowed.

    • feat:New function (Feature)

      “Feat” is used to indicate changes that introduce new functionality or features. Such changes are usually new features in the code base, not just bug fixes or code refactorings.

    • fix/to: Fix bug. These bugs may be discovered by the QA team or identified by developers during the development process.

      • The fix keyword is used for commits that directly solve a problem. fix should be used when creating a commit that contains necessary changes that directly fix the identified bug. This indicates that the submitted code introduced a solution and the problem was immediately resolved.
      • The to keyword is used for submissions that partially address the issue. In some complex remediation processes, multiple steps or commits may be required to fully resolve the issue. In this case, initial and intermediate commits should use to tags to indicate that they contribute to the final solution but do not completely solve the problem. Submissions that ultimately resolve a problem should use the fix tag to indicate that the problem has been completely fixed.
    • docs: Documentation

      “docs” refers to changes to documentation, which includes changes to comments, README files, or other documentation in the code base. Commits with this prefix are typically used to update the documentation to reflect changes to the code, or to provide better understanding and usage instructions for the code.

    • style: Format

      “style” is used to indicate changes to the code format that do not affect the operation of the code. Usually includes style adjustments such as spaces, indents, and line breaks.

    • refactor: Refactoring (that is, code changes that are not new features or bug fixes)

      “Refactor” means refactoring the code, that is, modifying the structure and implementation of the code without affecting its external behavior. The purpose of refactoring is to improve code readability, maintainability, and performance, not to introduce new features or fix bugs.

    • perf: Optimization related, such as improving performance and experience

      “perf” indicates changes related to performance optimization. This may include modifications to algorithms, data structures, or code implementations to improve code execution efficiency and user experience.

    • test: Add test

      “test” means adding tests, including unit tests, integration tests, or other types of tests.

    • chore: changes to the build process or auxiliary tools

      “chore” indicates changes to the build process or auxiliary tools. This may include updating build scripts, configuration files, or other build and tooling related content.

    • revert: Roll back to the previous version

      “revert” is used to roll back to a previous version and undo previous commits.

    • merge: code merge

      “Merge” means to merge the code, usually after the branch development is completed, the code will be merged back to the main line.

    • sync: Synchronize mainline or branch bugs

      “sync” means synchronizing bugs on the main line or branches, and is usually used to solve problems introduced by merges.

  2. Scope (optional)

    scope is used to describe the scope of influence of commit, such as data layer, control layer, view layer, etc., which varies depending on the project.

    For example, if Dao or Controller is modified, you can add a statement indicating that these scopes are affected, which helps to understand more clearly the scope of the submitted changes. For example:

    feat(Controller): Add user login function
    

    In this commit message, Controller is scope, indicating that this commit affects the control layer.

    fix(DataAccess): Fix data query logic
    

    In this commit message, DataAccess is scope, indicating that this commit affects the data access layer.

    If your changes affect more than one scope, you can use * instead.

  3. Subject (required)

    subject is a short description of the commit purpose, no more than 50 characters. The specifications are as follows:

    • Begin with a verb and use the first person present tense, such as change rather than changed or changes
    • lowercase first letter
    • No period at the end (.)

    For example:

    feat(UserAuth): implement user authentication
    

    In this commit message, implement user authentication is subject, which concisely and clearly describes the purpose of introducing user authentication functionality.

    fix(Validation): correct input validation logic
    

    In this commit message, correct input validation logic is subject, clearly stating the purpose of fixing the input validation logic.

1.2 Body

The Body part is a detailed description of this commit and can be divided into multiple lines. There are two points to note when writing Body.

  1. Use the first person present tense, such as change instead of changed or changes. This helps make the description more intuitive and coherent, enhancing readability.
  2. The motivation for the code change should be stated and how it compares to previous behavior. The Body section should not only describe the code change, but also explain why the change was made and what improvements were made compared to the previous code behavior. This helps other developers better understand the motivations and intentions behind code changes.

1.3 Footer

The Footer section is only used in two situations.

  1. Incompatible changes

    If the current code is incompatible with the previous version, the Footer section begins with BREAKING CHANGE, followed by a description of the change, the reason for the change, and the migration method.

  2. Close Issue

    If the current commit is for an issue, you can close the issue in the Footer section.

    Closes #234
    

    You can also close multiple issues at once.

    Closes #123, #245, #992
    

1.4 Example

  • Add user profile editing functionality

    feat(UserProfile): add user profile editing feature
    
    This commit introduces a new feature that allows users to edit their profiles
    directly from the user interface. The motivation behind this change is to
    enhance user interaction and provide a more seamless experience.
    
    Previously, users had to navigate to a separate editing page to update their
    profile information. With this new feature, users can now make changes
    efficiently from their profile page, eliminating unnecessary steps in the
    workflow.
    
    Changes included in this commit:
    - Added a new 'Edit Profile' button on the user profile page.
    - Implemented frontend components for profile editing.
    - Updated backend API to handle profile updates securely.
    
    By streamlining the profile editing process, we aim to improve overall user
    satisfaction and make our application more user-friendly. This enhancement is
    in response to user feedback, addressing the need for a more intuitive and
    accessible way to modify profile details.
    
    Closes #234
    
  • Correct input validation logic

    fix(Validation): correct input validation logic
    
    This commit addresses an issue related to input validation logic in the
    application. Previously, the validation process was not handling certain edge
    cases correctly, leading to unexpected behavior in specific scenarios.
    
    To resolve this issue, the validation logic has been revised to properly
    handle various input scenarios. This ensures that user input is thoroughly
    validated, reducing the likelihood of errors in the application.
    
    The changes made in this commit include:
    - Correcting boundary checks for user input.
    - Improving error messages for better user guidance.
    
    These adjustments align with our commitment to delivering a robust and
    reliable application experience.
    
    Closes #123
    
  • Optimize database queries

    refactor(DataAccess): optimize database queries
    
    In this commit, we have refactored the data access layer to optimize database
    queries and improve overall system performance. The existing query structure
    was identified as a bottleneck during performance testing, leading to longer
    response times.
    
    Changes made in this commit:
    - Reorganized database queries to reduce redundant operations.
    - Utilized database indexing for faster data retrieval.
    
    By optimizing database queries, we expect to see a significant improvement in
    system responsiveness and user experience.
    
    Closes #456
    

2 git commit tool

2.1 commitizen

Commitizen is a powerful tool for writing qualified Git commit messages. Using Commitizen can help teams follow unified commit message specifications and make commit history clearer and more readable.

First, install Commitizen globally with the following command:

npm install -g commitizen

Then, in the project directory, run the following command to make it support Angular’s Commit message format.

commitizen init cz-conventional-changelog --save --save-exact

This command will configure the project to support the Angular specification Commit Message. When executing a command, you can select other predefined specifications or create custom specifications.

Later, when you execute the git commit command, replace it with git cz. At this point, Commitizen will guide you through an interactive interface to generate a Commit Message that conforms to the specification.

img

In this interactive interface, you can select the type of submission (feat, fix, docs, etc.), scope, brief description (subject), and other relevant information. In this way, you ensure that the commit message conforms to the specification and provides more contextual information so that others can understand the purpose of the change.

Using Commitizen and standardized commit message formats can help improve the readability of the code base, facilitate the generation of automated change logs, and encourage developers to pay more attention to writing clear and unambiguous commit messages.

2.2 commitlint

commitlint is a tool for checking whether commit messages conform to specified specifications. It can help teams ensure the consistency and standardization of Git commit messages, especially when the project adopts specifications like Angular Commit Message Conventions.

  1. Install commitlint

    First, you need to install commitlint and its related configuration and rules. Typically, @commitlint/config-conventional is a configuration that is compatible with the Angular specification.

    npm install --save-dev @commitlint/config-conventional @commitlint/cli
    
  2. Configure commitlint

    Create the commitlint.config.js file in the project root directory and add the following content:

    module.exports = {<!-- -->
      extends: ['@commitlint/config-conventional'],
    };
    

    This configuration file uses the predefined rules in @commitlint/config-conventional to ensure compliance with common commit conventions.

  3. Configure Git hooks

    You can use the Husky hook tool to run commitlint before committing. First, install Husky:

    bashCopy code
    npm install --save-dev husky
    

    Then, add the following configuration in package.json:

    jsonCopy code
    "husky": {
      "hooks": {
        "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
      }
    }
    

    After this configuration, commitlint will be automatically run before each submission to check whether the submission message complies with the specification.

3 Generate Change log

If all your Commits conform to the Angular format, then when a new version is released, the Change log can be automatically generated using a script (Example 1, Example 2).

The generated document consists of the following three parts.

  • New features
  • Bug fixes
  • Breaking changes

Each section lists related commits and has links to those commits. Of course, the generated documentation allows manual modification, so you can add additional content before publishing.

conventional-changelog is a tool for generating Change log. Just run the following command.

npm install -g conventional-changelog
cd my-project
conventional-changelog -p angular -i CHANGELOG.md -w

The above command will not overwrite the previous Change log, but will only add the changes since the last release to the header of CHANGELOG.md.

If you want to generate a change log for all releases, run the following command instead.

conventional-changelog -p angular -i CHANGELOG.md -w -r 0

For convenience, you can write it into the scripts field of package.json.

{<!-- -->
  "scripts": {<!-- -->
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -w -r 0"
  }
}

From now on, just run the following command directly.

npm run changelog

This automated process not only simplifies the generation of change logs, but also ensures consistency and accuracy in recording project changes. The generated documents will be classified according to new features, bug fixes, major changes, etc., allowing users to quickly understand the changes in each version.

4 Reference materials

  1. How to standardize your Git commits? -Alibaba Cloud Developer
  2. Commit message and Change log writing guide-Ruan Yifeng’s web log