In order to provide valuable and consistent commit messages we follow the “imperative present tense” style for commit messages. Write the commit message as “Fix bug” and not “Fixed bug” or “Fixes bug”. This convention matches commit messages generated by commands like git merge and git revert.

http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html

In order to track the effects of changes onto the public interface, explicitly classify every commit into exactly one of three categories:

Category Description Operator
Neutral Only touches things “under the hood” and has no effect on the public API. =
Extending Extends the API by adding things. In rare cases this might break code due to things like identifier shadowing but is generally considered a “safe” change. +
Breaking Changes or removes public API elements. Will definitely break user code relying on these parts of the API surface. !

While working on a feature, you may then end up having many commits, such as:

+ Add new foo field to the bar object
= Tidy fixtures
= Refactor code
+ Add new foo field to the baz object
= Update fixture

Merging these directly into master from a branch would be noisy so from one branch and one pull-request (PR) we should squash commits into as few as possible, one if that makes sense to the features being merged. So the single commit in a PR would become:

+ Add Foo to the Bar and Baz JSON objects

Also, if you had a set of commits such as:

! Remove qux method from client
+ Add new grault method to the client
= Update tests

…then this would result in a commit using the most important operator:

! Change qux to grault method in client

All commits in the “Extending” and especially in the “Breaking” category should contain a dedicated paragraph (in addition to the summary line) explaining in what way the change breaks the API and why this is necessary/beneficial.