Skip to content

Instantly share code, notes, and snippets.

@janderssonse
Last active March 11, 2020 03:35
Show Gist options
  • Save janderssonse/e9a6971da33e538787fb3c5877ae2903 to your computer and use it in GitHub Desktop.
Save janderssonse/e9a6971da33e538787fb3c5877ae2903 to your computer and use it in GitHub Desktop.
Git Commit Message Guidelines

Commit Message Guidelines

Why?

Structured and clear project information

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.


Commit Message Format

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

screenshot

The <type>

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.

Optional <scope>

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>

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

The <body>

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.

Breaking Changes

start with the word BREAKING CHANGE: with a space or two newlines. The rest of the commit message is then used for this..

Referencing issues

Closed bugs should be listed on a separate line in the footer prefixed with "Closes" keyword like this:

Closes #234

or in case of multiple issues:

Closes #123, #245, #992

Generate a CHANGELOG

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

Ignore non-important commits

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)

Examples

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.

Pull Requests

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment