-
provide a structured git history
-
allow an easy generation of the CHANGELOG by a script
-
make it easy to ignore non-important commits
First, consider the following commit messages:
fix comment stripping closes resource fixing broken links Bit of refactoring Check whether links do exist and throw exception Added support for properties in documentation docs - various doc fixes replaced double line break with single when text is fetched from Google only, a special case fix!
Ask yourself:
-
Which part of the code has changed? Some of the commits are trying to tell a story. Can you guess in what scope where the commit was done - docs? the compiler? or somewhere else?
-
What tense is used? Notice the different tense used: fix - fixing?
-
Which commits are more or less interesting when browsing the history? For example, would commits introducing formatting changes (adding/removing spaces/empty lines, indentation), missing semi colons, comments, etc be interesting in a changelog or when debugging?
-
How does the line length will affect readability, especially when wrapped in a terminal?
By adhering to this guide, the above issues will be handled, and your git log will be clean, predictable and comprehensible.
A commit message consists of a header, a body and a footer. The header has a special format that includes a type, an optional scope and a subject:
<type>(<scope>): <subject> <BLANK LINE> <body> <BLANK LINE> <footer>
The header is mandatory and the scope of the header is optional.
The footer should contain a closing reference to an issue if any.
Many projects sticks to the 50/72 rule by convention
-
maximum 50 characters long first line (excluding type and scope)
-
description maximum 72 lines long
This allows the message to be easier to read on GitHub as well as in various git tools.
In general:
-
Make separate commits for logically separate changes.
-
Describe your changes well. Describe why the change is made
Project defined, examples could be:
-
build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
-
ci: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)
-
docs: Documentation only changes
-
feat: A new feature
-
license: Licensing compliance and changes
-
fix: A bug fix
-
perf: A code change that improves performance
-
refactor: A code change that neither fixes a bug nor adds a feature
-
style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
-
test: Adding missing tests or correcting existing tests
-
revert: If the commit reverts a previous commit, it should begin with
revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.
, where the hash is the SHA of the commit being reverted.
If applicable, the scope should be the name of the package affected (as perceived by the person reading the changelog generated from commit messages).
The following is a list of example scopes:
-
common
-
compiler
-
compiler-cli
-
core
-
http
-
router
The subject contains a succinct description of the change:
-
use the imperative, present tense: "change" not "changed" nor "changes". Read your commit message as "This commit will .."
-
don’t capitalize the first letter
-
no dot (.) at the end
Just as in the subject, use the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior.
The footer should contain any information about Breaking Changes and is also the place to reference GitHub issues that this commit Closes.
start with the word BREAKING CHANGE:
with a space or two newlines.
The rest of the commit message is then used for this..
Use these three sections in a changelog: new features, bug fixes, breaking changes. This list could be generated by a script when doing a release, along with links to related commits.
List of all subjects (first lines in commit message) since last release:
git log <last tag> HEAD --pretty=format:%s
New features in this release
git log <last release> HEAD --grep feature
You might want to ignore certain commits, like formatting changes
For example, when bisecting, you can ignore these by:
git bisect skip $(git rev-list --grep irrelevant <good place> HEAD)
Look at commits from the Git project
Various examples:
docs: update changelog to beta
feat(directive): add directives disabled/checked/multiple/readonly New directives for proper binding these attributes in older browsers. Add coresponding description, live examples and e2e tests. Closes #351
feat(compile): simplify isolate scope bindings Change the isolate scope binding options to: - @attr - attribute binding (including interpolation) - =model - by-directional model binding - &expr - expression execution binding Simplifies the terminology as well as number of choices available to the developer. It also supports local name aliasing from the parent. BREAKING CHANGE: isolate scope bindings definition has changed and the inject option for the directive controller injection was removed. To migrate the code follow the example below: Before: scope: { myAttr: 'attribute', myBind: 'bind', myExpression: 'expression', myEval: 'evaluate', myAccessor: 'accessor' } After: scope: { myAttr: '@', myBind: '@', myExpression: '&', // myEval - usually not useful, but in cases where the expression is assignable, you can use '=' myAccessor: '=' // in directive's template change myAccessor() to myAccessor } The removed `inject` wasn't generaly useful for directives so there should be no code using it.
-
To resolve conflicts, rebase pull request branches onto their target branch instead of merging the target branch into the pull request branch. This again results in a cleaner history without "criss-cross" merges.
-
When addressing review comments in a pull request, please fix the issue in the commit where it appears, not in a new commit on top of the pull request’s history. While this requires force-pushing of the new iteration of your pull request’s branch, it has several advantages:
-
Reviewers that go through (larger) pull requests commit by commit are always up-to-date with latest fixes, instead of coming across a commit that addresses their remarks only at the end.
-
It maintains a cleaner history without distracting commits like "Address review comments".
-
As a result, tools like git-bisect can operate in a more meaningful way.
-
Fixing up commits allows for making fixes to commit messages, which is not possible by only adding new commits.
If you are unfamiliar with fixing up existing commits, please read about rewriting history and
git rebase --interactive
in particular.
-