Summary
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|router|service-worker|
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve
│
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
The <type>
and <summary>
fields are mandatory, the (<scope>)
field is optional.
Type
Must be one of the following:
build
: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)ci
: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)docs
: Documentation only changesfeat
: A new featurefix
: A bug fixperf
: A code change that improves performancerefactor
: A code change that neither fixes a bug nor adds a featuretest
: Adding missing tests or correcting existing testsstyle
: (formatting, missing semi colons, etc; no production code change)chore
: (updating grunt tasks etc; no production code change)
Summary
Use the summary field to provide a succinct description of the change:
- use the imperative, present tense: “change” not “changed” nor “changes”
- don’t capitalize the first letter
- no dot (.) at the end
Make small commits
Let’s say you have two bugs that you just fixed. Each bug fix should produce a separate commit. By doing that you are creating an organized log of commits, which makes it easy for other developers to read and maintain the code base. It is a good practice to push code more often and not end up with a messy repo. Make small commits more frequently and avoid committing large chunks of code. This makes it easy to glance through the commit history and find what you are looking for. It is recommended that the use of git add . and git add -A should be in moderation and instead the focus should be on making frequent commits.
Commit complete and well tested code
Never commit incomplete code. This goes against the concept of committing. If you are working on a large task, try to break it down to smaller assignments and insure that each task is complete. Also, Get in the habit of testing your code prior to the commit stage.
Write good commit messages
Your commit log should tell a story. Therefore, Writing descriptive commit messages keeps your repository well managed and makes it easy to navigate through your commit log. Your commit message should be short, in present tense and explicitly say why you made the change.
Angular Commit Message Format
Refer to https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit-footer
Each commit message consists of a header, a body, and a footer.
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
The header
is mandatory and must conform to the Commit Message Header format.
The body
is mandatory for all commits except for those of type “docs”. When the body is present it must be at least 20 characters long and must conform to the Commit Message Body format.
The footer
is optional. The Commit Message Footer format describes what the footer is used for and the structure it must have.
Commit Message Header
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|router|service-worker|
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve
│
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
The <type>
and <summary>
fields are mandatory, the (<scope>)
field is optional.
Type
Must be one of the following:
- build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
- ci: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)
- docs: Documentation only changes
- feat: A new feature
- fix: A bug fix
- perf: A code change that improves performance
- refactor: A code change that neither fixes a bug nor adds a feature
- test: Adding missing tests or correcting existing tests
Summary
Use the summary field to provide a succinct description of the change:
- use the imperative, present tense: “change” not “changed” nor “changes”
- don’t capitalize the first letter
- no dot (.) at the end
Commit Message Body
Just as in the summary, use the imperative, present tense: “fix” not “fixed” nor “fixes”.
Explain the motivation for the change in the commit message body. This commit message should explain why you are making the change. You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
Commit Message Footer
The footer can contain information about breaking changes and deprecations and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to. For example:
BREAKING CHANGE: <breaking change summary>
<BLANK LINE>
<breaking change description + migration instructions>
<BLANK LINE>
<BLANK LINE>
Fixes #<issue number>
or
DEPRECATED: <what is deprecated>
<BLANK LINE>
<deprecation description + recommended update path>
<BLANK LINE>
<BLANK LINE>
Closes #<pr number>
Breaking Change section should start with the phrase “BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
Similarly, a Deprecation section should start with “DEPRECATED: " followed by a short description of what is deprecated, a blank line, and a detailed description of the deprecation that also mentions the recommended update path.
Limit the subject line to 50 characters
- 50 characters is not a hard limit, just a rule of thumb. Keeping subject lines at this length ensures that they are readable, and forces the author to think for a moment about the most concise way to explain what’s going on.
Capitalize the subject line
This is as simple as it sounds. Begin all subject lines with a capital letter.
For example:
- Accelerate to 88 miles per hour
Instead of:
- accelerate to 88 miles per hour
Use the imperative mood in the subject line
Imperative mood just means “spoken or written as if giving a command or instruction”. A few examples:
- Clean your room
- Close the door
- Take out the trash
The imperative can sound a little rude; that’s why we don’t often use it. But it’s perfect for Git commit subject lines. One reason for this is that Git itself uses the imperative whenever it creates a commit on your behalf.
For example, the default message created when using git merge
reads:
Merge branch 'myfeature'
And when using git revert
:
Revert "Add the thing with the stuff"
This reverts commit cc87791524aedd593cff5a74532befe7ab69ce9d.
Or when clicking the “Merge” button on a GitHub pull request:
Merge pull request #123 from someuser/somebranch
So when you write your commit messages in the imperative, you’re following Git’s own built-in conventions. For example:
- Refactor subsystem X for readability
- Update getting started documentation
- Remove deprecated methods
- Release version 1.0.0
Writing this way can be a little awkward at first. We’re more used to speaking in the indicative mood, which is all about reporting facts. That’s why commit messages often end up reading like this:
Fixed bug with YChanging behavior of X
And sometimes commit messages get written as a description of their contents:
More fixes for broken stuffSweet new API methods
To remove any confusion, here’s a simple rule to get it right every time.
A properly formed Git commit subject line should always be able to complete the following sentence:
- If applied, this commit will your subject line here
For example:
- If applied, this commit will refactor subsystem X for readability
- If applied, this commit will update getting started documentation
- If applied, this commit will remove deprecated methods
- If applied, this commit will release version 1.0.0
- If applied, this commit will merge pull request #123 from user/branch
Notice how this doesn’t work for the other non-imperative forms:
- If applied, this commit will
fixed bug with Y - If applied, this commit will
changing behavior of X - If applied, this commit will
more fixes for broken stuff - If applied, this commit will
sweet new API methods
Use the body to explain what and why vs. how
This commit from Bitcoin Core is a great example of explaining what changed and why:
commit eb0b56b19017ab5c16c745e6da39c53126924ed6
Author: Pieter Wuille <pieter.wuille@gmail.com>
Date: Fri Aug 1 22:57:55 2014 +0200
Simplify serialize.h's exception handling
Remove the 'state' and 'exceptmask' from serialize.h's stream
implementations, as well as related methods.
As exceptmask always included 'failbit', and setstate was always
called with bits = failbit, all it did was immediately raise an
exception. Get rid of those variables, and replace the setstate
with direct exception throwing (which also removes some dead
code).
As a result, good() is never reached after a failure (there are
only 2 calls, one of which is in tests), and can just be replaced
by !eof().
fail(), clear(n) and exceptions() are just never called. Delete
them.
Take a look at the full diff and just think how much time the author is saving fellow and future committers by taking the time to provide this context here and now. If he didn’t, it would probably be lost forever.
In most cases, you can leave out details about how a change has been made. Code is generally self-explanatory in this regard (and if the code is so complex that it needs to be explained in prose, that’s what source comments are for). Just focus on making clear the reasons why you made the change in the first place—the way things worked before the change (and what was wrong with that), the way they work now, and why you decided to solve it the way you did.
The future maintainer that thanks you may be yourself!
Reference
- https://medium.com/@nawarpianist/git-commit-best-practices-dab8d722de99
- https://chris.beams.io/posts/git-commit/
- https://www.conventionalcommits.org/en/v1.0.0/#specification
- https://github.com/thoughtbot/dotfiles/blob/master/gitmessage
- https://ruby-china.org/topics/15737
- https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716
- https://www.conventionalcommits.org/en/v1.0.0/