Skip to content

Commit 1a7e6c4

Browse files
committed
docs(writing_commits): improve documentation for writing commits best practice
1 parent 583acf4 commit 1a7e6c4

File tree

2 files changed

+142
-34
lines changed

2 files changed

+142
-34
lines changed

docs/tutorials/writing_commits.md

Lines changed: 141 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,159 @@
1-
For this project to work well in your pipeline, a commit convention must be followed.
1+
# Commit Message Best Practices
22

3-
By default, Commitizen uses the known [conventional commits][conventional_commits], but
4-
you can create your own following the documentation information over at
5-
[customization][customization].
3+
## About
64

7-
## Conventional commits
5+
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.
86

9-
If you are using [conventional commits][conventional_commits], the most important
10-
thing to know is that you must begin your commits with at least one of these tags:
11-
`fix`, `feat`. And if you introduce a breaking change, then you must
12-
add to your commit body the following `BREAKING CHANGE`.
13-
Using these three keywords will allow the proper identification of the semantic version.
14-
Of course, there are other keywords, but I'll leave it to the reader to explore them.
7+
You can also create your own custom commit convention by following the [customization documentation][customization].
158

16-
Note: You can also indicate breaking changes by adding an exclamation mark in the commit title
17-
(e.g., `feat!: breaking change`) by setting the `breaking_change_exclamation_in_title`
18-
configuration option to `true`. [Read more][breaking-change-config]
9+
## Conventional Commits Format
1910

20-
## Writing commits
11+
The Conventional Commits specification follows this structure:
2112

22-
Now to the important part: when writing commits, it's important to think about:
13+
```
14+
<type>[optional scope]: <description>
2315
24-
- Your future self
25-
- Your colleagues
16+
[optional body]
2617
27-
You may think this is trivial, but it's not. It's important for the reader to
28-
understand what happened.
18+
[optional footer]
19+
```
2920

30-
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].
21+
### Commit Types
3122

32-
### Recommendations
23+
Commit types categorize the nature of your changes. The most important types for semantic versioning are:
3324

34-
- **Keep the message short**: Makes the list of commits more readable (~50 chars).
35-
- **Talk imperative**: Follow this rule: `If applied, this commit will <commit message>`
36-
- **Think about the CHANGELOG**: Your commits will probably end up in the changelog,
37-
so try writing for it, but also keep in mind that you can skip sending commits to the
38-
CHANGELOG by using different keywords (like `build`).
39-
- **Use a commit per new feature**: If you introduce multiple things related to the same
40-
commit, squash them. This is useful for auto-generating CHANGELOG.
25+
- **`feat`**: Introduces a new feature (correlates with **MINOR** version increment)
26+
- **`fix`**: Patches a bug (correlates with **PATCH** version increment)
4127

42-
| Do's | Don'ts |
43-
| ---- | ------ |
28+
Other commonly used types include:
29+
30+
- **`docs`**: Documentation only changes
31+
- **`style`**: Code style changes (formatting, missing semicolons, etc.)
32+
- **`refactor`**: Code refactoring without changing functionality
33+
- **`perf`**: Performance improvements
34+
- **`test`**: Adding or updating tests
35+
- **`build`**: Changes to build system or dependencies
36+
- **`ci`**: Changes to CI configuration files
37+
- **`chore`**: Other changes that don't modify source or test files
38+
39+
!!! note
40+
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`.
41+
42+
### Breaking Changes
43+
44+
Breaking changes trigger a **MAJOR** version increment. You can indicate breaking changes in two ways:
45+
46+
1. **In the commit body or footer**:
47+
```
48+
feat(api): change authentication method
49+
50+
BREAKING CHANGE: The authentication API now requires OAuth2 instead of API keys.
51+
```
52+
53+
2. **In the commit title** (when enabled):
54+
```
55+
feat!: change authentication method
56+
```
57+
58+
To enable this syntax, set `breaking_change_exclamation_in_title = true` in your configuration. [Read more][breaking-change-config]
59+
60+
### Scope
61+
62+
An optional scope can be added to provide additional context about the area of the codebase affected:
63+
64+
```
65+
feat(parser): add support for JSON arrays
66+
fix(api): handle null response gracefully
67+
```
68+
69+
## Writing Effective Commit Messages
70+
71+
Well-written commit messages are crucial for maintaining a clear project history. When writing commits, consider:
72+
73+
- **Your future self**: You'll need to understand these changes months later
74+
- **Your team**: Clear messages help colleagues understand the codebase evolution
75+
- **Automated tools**: Good messages enable better changelog generation and versioning
76+
77+
### Best Practices
78+
79+
#### 1. Keep the Subject Line Concise
80+
81+
The subject line should be clear and concise (aim for ~50 characters). It should summarize what the commit does in one line.
82+
83+
**Good:**
84+
```
85+
fix(commands): handle missing user input gracefully
86+
feat(api): add pagination support
87+
```
88+
89+
**Avoid:**
90+
```
91+
fix: stuff
92+
feat: commit command introduced
93+
```
94+
95+
#### 2. Use Imperative Mood
96+
97+
Write commit messages in the imperative mood, as if completing the sentence: "If applied, this commit will..."
98+
99+
**Good:**
100+
```
101+
feat: add user authentication
102+
fix: resolve memory leak in parser
103+
```
104+
105+
**Avoid:**
106+
```
107+
feat: added user authentication
108+
fix: resolved memory leak in parser
109+
```
110+
111+
#### 3. Think About the Changelog
112+
113+
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`.
114+
115+
#### 4. One Feature Per Commit
116+
117+
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.
118+
119+
#### 5. Use the Body for Context
120+
121+
For complex changes, use the commit body to explain:
122+
- **Why** the change was made
123+
- **What** was changed (if not obvious from the subject)
124+
- **How** it differs from previous behavior
125+
126+
```
127+
feat(api): add rate limiting
128+
129+
Implement rate limiting to prevent API abuse. The system now
130+
enforces a maximum of 100 requests per minute per IP address.
131+
Exceeding this limit returns a 429 status code.
132+
```
133+
134+
### Examples
135+
136+
| ✅ Good Examples | ❌ Poor Examples |
137+
| ---------------- | ---------------- |
44138
| `fix(commands): bump error when no user provided` | `fix: stuff` |
45-
| `feat: add new commit command` | `feat: commit command introduced` |
139+
| `feat(api): add pagination to user list endpoint` | `feat: commit command introduced` |
140+
| `docs: update installation instructions` | `docs: changes` |
141+
| `refactor(parser): simplify token extraction logic` | `refactor: code cleanup` |
142+
143+
## Character Encoding
144+
145+
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].
146+
147+
By default, Commitizen uses `utf-8` encoding. You can configure a different encoding through the `encoding` [configuration option][configuration].
148+
149+
## Related Documentation
150+
151+
- [Conventional Commits Specification][conventional_commits]
152+
- [Custom Commit Conventions][customization]
153+
- [Commit Configuration Options](../config/commit.md)
46154
47155
[customization]: ../customization/config_file.md
48156
[conventional_commits]: https://www.conventionalcommits.org
49-
[cz_emoji]: https://commitizen-tools.github.io/commitizen/third-party-commitizen/#cz-emoji
157+
[cz_emoji]: ../third-party-plugins/cz-emoji.md
50158
[configuration]: ../config/commit.md#encoding
51159
[breaking-change-config]: ../config/commit.md#breaking_change_exclamation_in_title

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ nav:
5555
- Customized Python Class: "customization/python_class.md"
5656
- Changelog Template: "customization/changelog_template.md"
5757
- Tutorials:
58-
- Writing commits: "tutorials/writing_commits.md"
58+
- Commit Message Best Practices: "tutorials/writing_commits.md"
5959
- Managing tags formats: "tutorials/tag_format.md"
6060
- Auto check commits: "tutorials/auto_check.md"
6161
- Auto prepare commit message: "tutorials/auto_prepare_commit_message.md"

0 commit comments

Comments
 (0)