Conventional commits is a set of rules for writing clear and concise commit messages in a human and machine readable format. On the human side, this convention ensures collaborators understand changes and the motivation for such changes at a glance. On the machine side of things, conventional commits allow the easy creation of a standard commit history that automation tools can operate on.
Writing a conventional commit message
All LinkORB teams collaborating on a Git repository use conventional commit messages written in the following format:
<type>[(<scope>)]: <subject> #<cardNumber>
<EMPTY LINE>
[body]
<EMPTY LINE>
[footer]
The commit message must have a header, an optional body, and an optional footer.
Write a concise commit message header
The commit message’s header is a short sentence that states the purpose of a commit. It must start with a conventional commit type and preferably terminate with the related HQ card number prefixed by # as shown in the following synopsis.
<type>[(optional scope)]: <subject> #<cardNumber>
While terminating a commit message’s header with an existing HQ card number is preferred, #0000 may be used to terminate a commit message’s header for commits that are unrelated to an existing HQ card.
The following describe elements of a conventional commit header:
- type: The type of change introduced by a commit. It’s usually feat, fix, docs, chore, test, or docs. See commit types for more information.
- scope: An optional one-word category that provides additional context about part(s) of the codebase impacted.
- subject: A one-sentence, imperative mood, present tense description of the change(s).
- cardNumber: The card number of the associated HQ work item. E.g.
#4096.
Examples:
docs: add auto email to sys architecture #4096
feat(api): email customer when product ships #3072
An imperative mood present tense sentence demands an action. For example, implement one-click copy button for code blocks instead of implemented one-click copy button for code blocks.
Commit types
| Type | Description | Example |
|---|---|---|
| feat | Non-breaking change which adds new functionality | feat: auto refresh messages #1024 |
| fix | Non-breaking change which fixes a bug or an issue | fix: expired token loop #2048 |
| chore | General tasks or anything that doesn’t fit the other commit types | chore: replace outdated links #3072 |
| chore(deps) | Changes to dependencies | chore(deps): replace Markdown framework #4096 |
| test | Adds or modifies a test | test: add login e2e tests #2048 |
| docs | Creates or updates documentation | docs: update commit conventions #1024 |
| style | Changes that do not affect the meaning and function of code | style: update installation & usage guide #1024 |
| perf | Code change that improves performance | perf: reduce load time by 50% #4096 |
| revert | Reverts a commit | revert: remove leaked secret #2048 |
| refactor | Code change that neither fixes a bug nor adds a new feature | refactor: move controller to separate module #3072 |
| ci | Changes to continuous integration or delivery scripts/files | ci: update commit msg validation #4096 |
Commit messages for merge operations are auto-generated. They do not require a commit type nor a card number.
A note on breaking changes
A breaking change is a modification that requires dependent actors to also make a corresponding change; such as additional required parameters to an existing function. Add an exclamation mark (!) to the end of the <type> field (i.e. <type>![optional scope]: subject) to indicate a breaking change. See Write an optional commit message footer for more information on breaking changes.
Semantic versioning with conventional commits
A GitHub Action workflow validates each commit and PR against the standards in this document, and triggers workflows if the commit message is compliant. For example, fix, style, test, refactor, and perf commit types will trigger a patch release (e.g. from v1.1.1 to v1.1.2). feat, will trigger a minor release (e.g. from v1.1.1 to v1.2.0), and a breaking change (<type>!) will trigger a major release (e.g. v1.1.1 to v2.0.0).
Write an optional commit message body
A commit message’s body is optional. If you decide a commit message needs a body, do the following:
- Leave a blank line between the header (subject line above) and the body
- Summarize changes and the motivation for such changes
- Contrast previous and current behaviour (if necessary)
- Group related subjects into paragraphs
Write an optional commit message footer
Like a commit message’s body, the footer is also optional. Use the footer to summarise supplemental information such as:
- A description of breaking changes
- Issues that the commit closes
- Dependent work item identifiers (HQ cards)
- Links to related topic(s)
- Co-authors
A breaking change is a modification that will require dependent actors to also make a corresponding change; such as additional required parameters to an existing function.
If the commit introduces a breaking change:
- Leave a blank line between other sections of the footer and the
BREAKING CHANGEsection. - Begin messages about breaking changes with the words
BREAKING CHANGE:.
Please note that all the guidelines in this document also apply to changes committed to a repository through GitHub’s UI.
Modify your last commit
git commit --amend can be used to update the content of your last commit. If you notice a mistake in your last commit message, simply run the following command to reopen the commit message in a text editor.
git commit --amend