From cdf6a3d4744f336c61e162bf466f2f5b20aee4a6 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung Date: Wed, 10 Dec 2025 22:35:36 +0800 Subject: [PATCH] docs(writing_commits): improve documentation for writing commits best practice --- docs/tutorials/writing_commits.md | 175 ++++++++++++++++++++++++------ mkdocs.yml | 2 +- 2 files changed, 143 insertions(+), 34 deletions(-) diff --git a/docs/tutorials/writing_commits.md b/docs/tutorials/writing_commits.md index a56d6494d..b8aa7f30f 100644 --- a/docs/tutorials/writing_commits.md +++ b/docs/tutorials/writing_commits.md @@ -1,51 +1,160 @@ -For this project to work well in your pipeline, a commit convention must be followed. +# Commit Message Best Practices -By default, Commitizen uses the known [conventional commits][conventional_commits], but -you can create your own following the documentation information over at -[customization][customization]. +## About -## Conventional commits +For Commitizen to work effectively in your development pipeline, commits must follow a consistent convention. By default, Commitizen uses the [Conventional Commits][conventional_commits] specification, which provides a standardized format for commit messages that enables automatic versioning and changelog generation. -If you are using [conventional commits][conventional_commits], the most important -thing to know is that you must begin your commits with at least one of these tags: -`fix`, `feat`. And if you introduce a breaking change, then you must -add to your commit body the following `BREAKING CHANGE`. -Using these three keywords will allow the proper identification of the semantic version. -Of course, there are other keywords, but I'll leave it to the reader to explore them. +You can also create your own custom commit convention by following the [customization documentation][customization]. -Note: You can also indicate breaking changes by adding an exclamation mark in the commit title -(e.g., `feat!: breaking change`) by setting the `breaking_change_exclamation_in_title` -configuration option to `true`. [Read more][breaking-change-config] +## Conventional Commits Format -## Writing commits +The Conventional Commits specification follows this structure: -Now to the important part: when writing commits, it's important to think about: +``` +[optional scope]: -- Your future self -- Your colleagues +[optional body] -You may think this is trivial, but it's not. It's important for the reader to -understand what happened. +[optional footer] +``` -Emojis may be added as well (e.g., see [cz-emoji][cz_emoji]), which requires the `utf-8`, or equivalent, character encoding to support unicode characters. By default, `commitizen` uses the `utf-8` character encoding, but a different encoding may be set through the `encoding` [configuration option][configuration]. +### Commit Types -### Recommendations +Commit types categorize the nature of your changes. The most important types for semantic versioning are: -- **Keep the message short**: Makes the list of commits more readable (~50 chars). -- **Talk imperative**: Follow this rule: `If applied, this commit will ` -- **Think about the CHANGELOG**: Your commits will probably end up in the changelog, - so try writing for it, but also keep in mind that you can skip sending commits to the - CHANGELOG by using different keywords (like `build`). -- **Use a commit per new feature**: If you introduce multiple things related to the same - commit, squash them. This is useful for auto-generating CHANGELOG. +- **`feat`**: Introduces a new feature (correlates with **MINOR** version increment) +- **`fix`**: Patches a bug (correlates with **PATCH** version increment) -| Do's | Don'ts | -| ---- | ------ | +Other commonly used types include: + +- **`docs`**: Documentation only changes +- **`style`**: Code style changes (formatting, missing semicolons, etc.) +- **`refactor`**: Code refactoring without changing functionality +- **`perf`**: Performance improvements +- **`test`**: Adding or updating tests +- **`build`**: Changes to build system or dependencies +- **`ci`**: Changes to CI configuration files +- **`chore`**: Other changes that don't modify source or test files + +!!! note + While `feat` and `fix` directly affect semantic versioning, other types (like `build`, `chore`, `docs`) typically don't trigger version bumps unless they include a `BREAKING CHANGE`. + +### Breaking Changes + +Breaking changes trigger a **MAJOR** version increment. You can indicate breaking changes in two ways: + +1. **In the commit body or footer**: + ``` + feat(api): change authentication method + + BREAKING CHANGE: The authentication API now requires OAuth2 instead of API keys. + ``` + +2. **In the commit title** (when enabled): + ``` + feat!: change authentication method + ``` + + To enable this syntax, set `breaking_change_exclamation_in_title = true` in your configuration. [Read more][breaking-change-config] + +### Scope + +An optional scope can be added to provide additional context about the area of the codebase affected: + +``` +feat(parser): add support for JSON arrays +fix(api): handle null response gracefully +``` + +## Writing Effective Commit Messages + +Well-written commit messages are crucial for maintaining a clear project history. When writing commits, consider: + +- **Your future self**: You'll need to understand these changes months later +- **Your team**: Clear messages help colleagues understand the codebase evolution +- **Automated tools**: Good messages enable better changelog generation and versioning + +### Best Practices + +#### 1. Keep the Subject Line Concise + +The subject line should be clear and concise (aim for ~50 characters). It should summarize what the commit does in one line. + +**Good:** +``` +fix(commands): handle missing user input gracefully +feat(api): add pagination support +``` + +**Avoid:** +``` +fix: stuff +feat: commit command introduced +``` + +#### 2. Use Imperative Mood + +Write commit messages in the imperative mood, as if completing the sentence: "If applied, this commit will..." + +**Good:** +``` +feat: add user authentication +fix: resolve memory leak in parser +``` + +**Avoid:** +``` +feat: added user authentication +fix: resolved memory leak in parser +``` + +#### 3. Think About the Changelog + +Your commits will likely appear in the automatically generated changelog. Write messages that make sense in that context. If you want to exclude a commit from the changelog, use types like `build`, `chore`, or `ci`. + +#### 4. One Feature Per Commit + +Keep commits focused on a single change. If you introduce multiple related changes, consider squashing them into a single commit. This makes the history cleaner and improves changelog generation. + +#### 5. Use the Body for Context + +For complex changes, use the commit body to explain: + +- **Why** the change was made +- **What** was changed (if not obvious from the subject) +- **How** it differs from previous behavior + +``` +feat(api): add rate limiting + +Implement rate limiting to prevent API abuse. The system now +enforces a maximum of 100 requests per minute per IP address. +Exceeding this limit returns a 429 status code. +``` + +### Examples + +| ✅ Good Examples | ❌ Poor Examples | +| ---------------- | ---------------- | | `fix(commands): bump error when no user provided` | `fix: stuff` | -| `feat: add new commit command` | `feat: commit command introduced` | +| `feat(api): add pagination to user list endpoint` | `feat: commit command introduced` | +| `docs: update installation instructions` | `docs: changes` | +| `refactor(parser): simplify token extraction logic` | `refactor: code cleanup` | + +## Character Encoding + +Commitizen supports Unicode characters (including emojis) in commit messages. This is useful if you're using commit message formats that include emojis, such as [cz-emoji][cz_emoji]. + +By default, Commitizen uses `utf-8` encoding. You can configure a different encoding through the `encoding` [configuration option][configuration]. + +## Related Documentation + +- [Conventional Commits Specification][conventional_commits] +- [Custom Commit Conventions][customization] +- [Commit Configuration Options](../config/commit.md) [customization]: ../customization/config_file.md [conventional_commits]: https://www.conventionalcommits.org -[cz_emoji]: https://commitizen-tools.github.io/commitizen/third-party-commitizen/#cz-emoji +[cz_emoji]: ../third-party-plugins/cz-emoji.md [configuration]: ../config/commit.md#encoding [breaking-change-config]: ../config/commit.md#breaking_change_exclamation_in_title diff --git a/mkdocs.yml b/mkdocs.yml index ac1fbfa09..cb49eacdd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -55,7 +55,7 @@ nav: - Customized Python Class: "customization/python_class.md" - Changelog Template: "customization/changelog_template.md" - Tutorials: - - Writing commits: "tutorials/writing_commits.md" + - Commit Message Best Practices: "tutorials/writing_commits.md" - Managing tags formats: "tutorials/tag_format.md" - Auto check commits: "tutorials/auto_check.md" - Auto prepare commit message: "tutorials/auto_prepare_commit_message.md"