1# Commit message guidelines
  2
  3We have very strict rules over how commit messages must be formatted. This
  4format leads to easier to read commit history, and makes it possible to generate
  5a changelog for releases.
  6
  7<!-- mdformat-toc start --slug=github --maxlevel=4 --minlevel=2 -->
  8
  9- [Specification](#specification)
 10  - [Format overview](#format-overview)
 11  - [Type (required)](#type-required)
 12  - [Scope (optional)](#scope-optional)
 13  - [Subject (required)](#subject-required)
 14  - [Body (optional)](#body-optional)
 15    - [Anchors / Hyperlinks](#anchors--hyperlinks)
 16  - [Footer (optional, conditionally required)](#footer-optional-conditionally-required)
 17    - [Breaking changes](#breaking-changes)
 18
 19<!-- mdformat-toc end -->
 20
 21## Specification<a name="specification"></a>
 22
 23Commit subjects and messages should follow the format specified below, which is
 24a superset of the conventional commits specification
 25[version `1.0.0`][cc-1.0.0].
 26
 27**A superset? What's different?**
 28
 29We require just one small change from the spec:
 30
 31- Appending the type and scope with `!` is _always_ required for breaking
 32  changes. This is done by improve visibility of breaking changes in the commit
 33  log.
 34
 35### Format overview<a name="format-overview"></a>
 36
 37```
 38<type>[scope][!]: <subject>
 39
 40[optional body]
 41
 42[optional footer(s)]
 43```
 44
 45### Type (required)<a name="type-required"></a>
 46
 47Valid values for `type` MUST be one of the following:
 48
 49| Type       | Description                                          |
 50| ---------- | ---------------------------------------------------- |
 51| `build`    | Changes that affect the build system or dependencies |
 52| `ci`       | Changes to the CI configuration files                |
 53| `docs`     | Changes consisting only of documentation changes     |
 54| `feat`     | A new feature                                        |
 55| `fix`      | A bug fix                                            |
 56| `perf`     | Changes that improve performance                     |
 57| `refactor` | A change that neither fixes a bug or adds a feature  |
 58| `test`     | Adding missing tests or correcting existing tests    |
 59
 60### Scope (optional)<a name="scope-optional"></a>
 61
 62The scope should be the app or package name as it would be perceived by a person
 63reading the changelog.
 64
 65The following scopes are supported:
 66
 67- `api`
 68- `bridge`
 69- `bridge/github`
 70- `bridge/gitlab`
 71- `bridge/jira`
 72- `bugs`
 73- `cache`
 74- `cli`
 75- `config`
 76- `git`
 77- `tui`
 78- `web`
 79
 80There are a few exceptions to the "use the package name" rule:
 81
 82- `changelog`: used for changes related to the changelog or its generation
 83- `dev-infra`: used for developer-centric changes (docs, scripts, tools, etc)
 84- `treewide`: used for repo-wide changes (e.g. bulk formatting, refactoring)
 85- _none / unset_: useful for `build`, `ci`, and `test` (if changing a test lib,
 86  or multiple tests)
 87
 88### Subject (required)<a name="subject-required"></a>
 89
 90The subject should contain a succinct, descriptive summary of the change.
 91
 92- Use the imperative, present tense: "change" not "changed" or "changes"
 93- Do not use capital letters, except in acronyms (like `HTTP`)
 94- Do not end the subject with a `.` or `?` or any similar end-of-sentence symbol
 95
 96### Body (optional)<a name="body-optional"></a>
 97
 98The body is used to provide additional context: the _what_, _why_, and _how_ for
 99the change. Just as in the **subject**, use the imperative tense. The body
100should contain the motivation for the change, and contrast it with the previous
101behavior.
102
103#### Anchors / Hyperlinks<a name="anchors--hyperlinks"></a>
104
105If you include anchors, otherwise known as hyperlinks (or just "links") in the
106body, be sure to use the _reference style_ for anchor links.
107
108**Incorrect - do not use inline links**
109
110```
111Lorem ipsum dolar [sit amet](https://foo.com), consectetur adipiscing elit. In
112hendrerit orci et risus vehicula venenatis.
113```
114
115**Correct - use reference style links**
116
117Both of the below examples are valid.
118
119```
120Lorem ipsum dolar [sit amet][0], consectetur adipiscing elit. In hendrerit orci
121et risus vehicula venenatis.
122
123[0]: https://foo.com
124```
125
126```
127Lorem ipsum dolar sit amet [0], consectetur adipiscing elit. In hendrerit orci
128et risus vehicula venenatis.
129
130[0]: https://foo.com
131```
132
133### Footer (optional, conditionally required)<a name="footer-optional-conditionally-required"></a>
134
135The footer should contain any information about **breaking changes** (see below)
136and is also the place to reference issues that the change closes, if any.
137
138**Examples**
139
140```
141Closes: #000
142Closes: git-bug/git-bug#000
143Fixes: #000
144Ref: https://domain.com/some-page/foo/bar
145Ref: https://github.com/git-bug/git-bug/discussions/000
146```
147
148#### Breaking changes<a name="breaking-changes"></a>
149
150To indicate that a commit introduces a breaking change, append `!` after the
151type and scope (**this is required**). You can optionally provide additional
152information (for example, migration instructions) by adding a `BREAKING-CHANGE`
153trailer to the footer. This additional information will be shown in the
154changelog.
155
156> [!NOTE]
157> Breaking changes in this repository **always require** the `!` suffix in order
158> to improve visibility of breaking changes in the commit log.
159
160**Examples**
161
162Below are commit message examples you can use as references for writing a commit
163message for a breaking change.
164
165**Unscoped breaking change without additional information**
166
167```
168feat!: remove the ABC bridge
169```
170
171**Scoped breaking change without additional information**
172
173```
174feat(config)!: remove configuration option: foo.bar
175```
176
177**Scoped breaking change with additional information**
178
179```
180feat(config)!: remove option: foo.bar
181
182BREAKING-CHANGE: Users should migrate to `bar.baz`
183```
184
185**Scoped breaking change with multiple lines**
186
187If your breaking change description spans multiple lines, be sure to indent each
188subsequent line with at least one space so that the message is parsed correctly.
189
190```
191feat(config)!: remove option: foo.bar
192
193BREAKING-CHANGE: Users should migrate to `bar.baz` in order to continue
194 operating the tool and avoid a parsing error when the configuration is loaded,
195 which would throw an error stating that the `foo.bar` option doesn't exist.
196```
197
198[cc-1.0.0]: https://www.conventionalcommits.org/en/v1.0.0/#specification