
How to Write a Git Commit Message (2014) - deyton
https://chris.beams.io/posts/git-commit/
======
jph
My team uses a git commit message convention that helps us read fast and also
is parsable by toolchains.

We agree on a short list of leading active verbs:

Add = Create a capability e.g. feature, test, dependency.

Cut = Remove a capability e.g. feature, test, dependency.

Fix = Fix an issue e.g. bug, typo, accident, misstatement.

Bump = Increase the version of something e.g. dependency.

Make = Change the build process, or tooling, or infra.

Start = Begin doing something; e.g. create a feature flag.

Stop = End doing something; e.g. remove a feature flag.

Refactor = A code change that MUST be just a refactoring.

Reformat = Refactor of formatting, e.g. omit whitespace.

Optimize = Refactor of performance, e.g. speed up code.

Document = Refactor of documentation, e.g. help files.

~~~
jph
Feedback on this git commit message convention is welcome, and so are pull
requests:

[https://github.com/joelparkerhenderson/git_commit_message](https://github.com/joelparkerhenderson/git_commit_message)

~~~
ibgib
I would recommend putting it in a git commit template if you haven't already.
This will make it easier to implement the convention IMO.

------
trjordan
There are so many articles like this, and all of them focus so much on
prescriptive rules for commit messages. There's a similar set of articles on
how to deal with branching and merging. Somehow, everybody comes to slightly
different conclusions.

The discussion that needs to happen before this is to understand what tools
you want to make available to your developers in the future. Using git's
history as a first class debugging tool is powerful, but it's by no means
mandatory to provide. There's also a real cost to providing each of the tools.

\- Do you want bisect to be available? Well, then you should have most commits
represent a fully-functional version of the software. Consider squashing
branches when you merge them.

\- Do you want narrative documentation around strange choices? Fine-grained
commits are a great place to put those thoughts, but they may discourage devs
from writing those thoughts in inline comments.

\- Do you want ownership via git blame? Line-by-line changes may help you
identify who wrote the code, but that might prevent your developers from ever
fully transferring ownership, which could create bottlenecks in startups that
have a few long-tenure devs and a lot of recently hired devs.

I really like to think of git history as a context tool, like monitoring or
unit testing or documentation. It's worthwhile to sit down with your team,
define what you want them to be able to do with commit history, and build your
commit style from there.

------
data_hope
My personal, subjective impression: Commits are getting smaller and smaller
nowadays. As in: In the subversion days, many people commited only few times a
day, sometimes not for several days. SVN commits of course involved a sync
with the server (a "push" in git lingo), and thus usually represented a much
larger increment with a substantial change to the code base [X]

With git, it became very common to structure changes to a code base in many,
very small commits. Rename a variable? Commit. Write some docs? Commit. Of
course, the overall changes when developing a feature did not become smaller,
they are now just distributed over many more commits. So I'd argue that a SVN
commit was often conceptionally closer to what we now have with a git pull-
request.

Why does this matter? Because It is kind of hard and not helping anyone if you
describe your renaming of a local variable with an extensive docstring.

What I do miss however, is a good description of the overall change. I.e. now
often the description in the merge commit is just the autogenerated message,
but this is where I would like people to really take the time and describe the
change extensively. This is why I like `--squash` merges, because they let
people focus on the relevant parts in their description. _I know, rewriting
history is bad, but overall, I favour reading a history book than 18th century
newspapers._

[X] not saying that there weren't small one-line-change commits, but overall
they were rarer.

~~~
wst_
I find tons of small commits a clutter and waste of time. I don't see any
reason for doing so. On the contrary I can see disadvantage - reading and
understanding a history later may become difficult task. After all what counts
is your full chunk of work, reviewed via pull request, and merged to master.
It should be treated as a whole.

Has it really become so common with git? I don't see such trend around me.

~~~
pm215
The main reason I request commits to be split up is for ease of code review.
It's much easier to review three commits that each do one easily
comprehensible small thing than one commit that does three things at once.
It's also better if you find there's a bug -- you can bisect down to a commit
that's fairly small where the bug should be easy to see, rather than one
that's enormous and where the bug is hard to find among all the other changes.

~~~
wst_
I think it is a matter of definition of "small" and "enormous". If you have a
small thing, easily comprehensible, but big enough for it to be a complete
piece of work. Then probably you also have separate task for it, and the
change you introduce doesn't break the build. So it the end it's just a
perfect candidate for pull request.

But note the comment above mentioned a commit for variable change. Or a commit
for adding some comment sentence. Nano commits they are.

Sure, tasks should be small, easy to get, easy to review. But there must be a
balance. Going to extreme, both ways, doesn't do any good.

------
stared
I really recommend angular-style commit messages:
[https://github.com/angular/angular.js/blob/master/CONTRIBUTI...](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)

type(scope) message

e.g.

feat(button) added play button

Types are:

\- feat: A new feature

\- fix: A bug fix

\- docs: Documentation only changes

\- style: Changes that do not affect the meaning of the code (white-space,
formatting, missing semi-colons, etc)

\- refactor: A code change that neither fixes a bug nor adds a feature

\- perf: A code change that improves performance

\- test: Adding missing or correcting existing tests

\- chore: Changes to the build process or auxiliary tools and libraries such
as documentation generation

~~~
jph
If you like this format, then you may want to try a similar format that uses
the same purpose, plus uses words that easier to read and that make more sense
to people in more cultures.

We use Add, Fix, Refactor, Reformat, Optimize, etc.

See my comment on this thread or
[https://github.com/joelparkerhenderson/git_commit_message](https://github.com/joelparkerhenderson/git_commit_message)

~~~
stared
I don't mind command names.

However, in the linked article no visual separation between type and message
(and no scope) is something I consider less useful.

------
sleepychu
I've been writing commit messages this way for a little under a year (I think
this is the same guide I used when I was looking for a more consistent form to
write them and to avoid the dreaded -m "Fixed some things").

One thing I noticed is that it's increased my confidence in my commits; at the
moment that I go to write the commit message because I'm describing why I made
the decisions I did it breaks logical inconsistencies between what I've
actually done and what I think I've done. If I'm able to explain all the
change I'm much more confident that it's correct.

Another is that bad commit messages have trained people not to read them.
Often people will ask why I've made a change and then discover that the commit
message contains the answer to their question!

------
gregmac
The only one that really drives me crazy is

> Wrap the body at 72 characters

Why? Because the git CLI doesn't wrap properly? To borrow a quote, that seems
like a 'you' problem, not a me problem.

Maybe I'm just biased because these days I almost entirely interact with git
through a GUI (either desktop client or web interface), and though I use the
CLI occasionally (mostly for branch management, sometimes for quick commits) I
can't think of the last time I used it for _any_ type of history viewing --
pretty much any GUI is going to do a better job of that.

My team often uses markdown (mainly bulleted lists) and the output looks
terrible when you insert manual line breaks (because markdown interprets that
as meaning that you explicitly want a line break there) and you're viewing it
on a screen/viewport that is either larger or smaller than 72 characters wide.

Unless you're explicitly using a publishing format (eg, LaTeX, PDF,
postscript), the function of wrapping text should be a concern of the
rendering of the output, not the origin.

Am I missing something here? Is there any other reason to manually wrap text
besides the git CLI's handling of it as a viewer?

~~~
pbh101
Linus Torvalds answered exactly this question [0]. Not that that means you
should unblinkingly take it on authority, but the original reasoning is: the
renderer doesn't alway know when a line should be wrapped. Examples: a stack
trace, or long log line, or essentially any other quoted artifact that has a
specific pre-determined format.

The relevant quote from the link:

    
    
      Some things should not be word-wrapped. They may be some kind of
      quoted text - long compiler error messages, oops reports, whatever.
      Things that have a certain specific format.
    
      The tool displaying the thing can't know. The person writing the
      commit message can. End result: you'd better do word-wrapping at
      commit time, because that's the only time you know the difference.
    

[0]
[https://github.com/torvalds/linux/pull/17#issuecomment-56611...](https://github.com/torvalds/linux/pull/17#issuecomment-5661185)

EDIT: small clarification and formatting

~~~
rodovich
I understand this rationale, but I think most developers will encounter commit
messages written by bozos who don't press enter after every 72 characters, far
more frequently than commit messages that contain stack traces or other fixed-
format artifacts. (Disclosure: I am one of these bozos.) The tool flubs every
non-wrapped paragraph just so it can preserve the occasional blob of ASCII
art.

If the tool applied reasonable wrapping heuristics and got it wrong once in a
while, it could easily offer a `--no-wrap` option to let users see the message
exactly as it was composed.

------
SEJeff
How to write good git commit messages literally from the person who wrote git
(Linus Torvalds):

[https://github.com/torvalds/subsurface-for-
dirk/blob/0f58510...](https://github.com/torvalds/subsurface-for-
dirk/blob/0f58510ce0244513521296b75281fcc32f72a931/README#L92-L119)

I always send this to people as I teach them git.

~~~
tyingq
Some more from Linus:
[https://github.com/torvalds/linux/pull/17#issuecomment-56637...](https://github.com/torvalds/linux/pull/17#issuecomment-5663733)

------
jupp0r
I really like that Gerrit code reviews allow reviewers to comment on the
commit message in the same way as on the code. The way to ensure useful commit
message practices is the review process, if you ask me.

------
ibgib
1\. Git commit templates. 2\. Emoji. 3\. Bullets in body.

1\. Any article on structured git commit messages should mention git commit
templates! [https://robots.thoughtbot.com/better-commit-messages-
with-a-...](https://robots.thoughtbot.com/better-commit-messages-with-a-
gitmessage-template)

I use a commit template for structure, as well as reducing boilerplate for
expressive messages. Here is my default template on ibgib:
[https://github.com/ibgib/ibgib/blob/master/git-commit-
templa...](https://github.com/ibgib/ibgib/blob/master/git-commit-template.txt)

2\. I also use emoji (with a key there in the git commit template for
reference) to communicate concepts like implemented, bug fix, etc., in a
single emoji character. Note though that it is inappropriate when you start to
do a pull request, as not all git message viewers will display the emoji. But
I find it very useful FTMP.

3\. Bullets are a simple way to enable both terse and structured comments
within a commit.

------
ratherbefuddled
Does nobody else require there to be at least one issue tracker reference in
the commit message these days? It makes automating stuff like release notes
much easier.

~~~
emodendroket
So then you have like fifty hashes attached to the ticket?

------
aduitsis
This reminds a recent tweet by Rob Pike:

Goals imposed by git: Commit subject < 65 "chars", commit message lines < 70
"chars".

All in service of the punch card god Hollerithus.

[https://twitter.com/rob_pike/status/837410954518286337](https://twitter.com/rob_pike/status/837410954518286337)

------
bjourne
It doesn't matter that much. Some things in programming mater a lot, like
consistent indentation and casing. Some things doesn't, like perfectly
formatted commit messages. whether the verbs in commit messages should be in
imperative or present tense is just too much.

I can tell you that I have been programming for a very long time. So if
someone asks me "Why does it MATTER if lines are longer than 80 characters?"
then I can answer "Because it means that the distribution of line-lengths will
be more uniform, meaning that you will be able to fit more code on the screen,
meaning that the amount of scrolling you'll have to do when trying to
understand the code is greatly reduced." And scrolling interrupts your focus,
which is bad. But if I ask someone, "Why does it MATTER if verbs are in
present or imperative tense?" no one can answer.

~~~
niteshade
One reason I can think of for using the imperative tense is to use commit
messages to generate changelogs. AngularJS does it this way, wouldn't be
surprised if there were others.

------
CydeWeys
We've been using this format on our project for over a year now. Our commit
history looks nice as a result:
[https://github.com/google/nomulus/commits/master](https://github.com/google/nomulus/commits/master)

------
phailhaus
Git has zero opinion on when you commit or what the messages are. Commits are
made in private. Commits are also immutable. This is a losing battle.

If you use a code management tool like BitBucket or GitHub, it seems like the
unit of work is less a commit and more a PR. A PR's description can always be
edited and refined for future engineers, and a PR (almost) always represents a
block of work that can be reverted. Instead of creating a hundred different
approaches to writing commits that engineers essentially have to get right the
first time, why not just focus on documentation in the form of PR's? It seems
like if you could trivially tie a commit back to the PR and ticket it came
from, most of these problems would be solved.

~~~
CydeWeys
Private commits aren't immutable at all. You can change anything about them up
until you push them to a remote repository that other people are syncing from.
I routinely squash a bunch of private commits together before issuing a public
PR, for example.

~~~
phailhaus
Commits are immutable; when you squash commits you're replacing them with new
ones and rewriting the history. And since there is no difference between your
local repository and the remote one, the reason why you wouldn't squash
commits on the remote repository is to be nice to your coworkers.

So unlike PR's, if your coworkers criticize your commit messages it's already
too late.

~~~
CydeWeys
> And since there is no difference between your local repository and the
> remote one

Uhh, there's plenty of difference between your local repository and the remote
one. One is local and used just by you and one is remote and used by many, for
starters. Changes aren't automatically synced between them. You can rewrite
commits locally to your heart's content (which I do all the time). You aren't
"locked in" to anything until you've pushed it to a shared repository and
someone syncs from it.

~~~
phailhaus
All those differences you mentioned are not related to implementation. The
remote repo is functionally identical to your local repo. You can "rewrite
commits to your heart's content" on the remote repo too, there is nothing
stopping you. Like I said, the only reason you don't is to be nice to your
coworkers.

By the time somebody else criticizes your commit messages, you've already
pushed. It's too late. All that time you had while the commit was local-only
means nothing, unless you brought your coworkers over to your computer to
review your commits before creating a PR. Expecting developers to get commits
right the first time (before pushing) is not a sustainable solution.

------
achr2
The main issue with commits is that they end up representing more than a
single logical change.

Are there any tools that allow you to initiate a commit as an 'intention
stack' for work I am about to do, rather than work I have already done?

I'd love to be able to write an intent message "refactor XYZ.." before
starting in on that activity, then when I have to go down another rabbit hole
in the middle I push another intent message to the stack, then pop back out
afterward and continue with XYZ. The final overall commit message could be
auto generated from the initial intention and all tangents.

~~~
jononor
Commit each of the changes you make, including possible detours etc. Then use
git rebase -i to work it into a sane history later.

------
pbosko
My team uses task number and title as a commit message. We just can't fit all
the description from task into one line of comment. So, when we look at git
blame - we get a reference to a task in project management tool where we can
find all the reasons behind a given change.

If there are more commits for the same task, all of them bare the same commit
message. After each review, we add a comment to project management tool. That
way we focus only on newer commits when performing another round of reviews.

Every other attempt to describe changes and intentions in one line seems
doomed to me.

------
kevinmannix
I've really welcomed the recent GitHub features such as "squash & merge" and
"rebase & merge". Instead of parsing through 200 commits of "typo", "lint",
"spacing", a feature is placed in a compact diff with the feature title &
related task id as the commit message.

A commit should be a unit of work. Tests should pass before and after. The
commit message should describe the change. Ensuring that you have a good
commit message then influences what content you contain in a commit.

------
jdiez17
I've found that writing commit messages by stating the problem in the subject,
and an explanation of the solution in the body makes them very clear and
descriptive.

For example:

    
    
        Problem: Windows build script requires edit of VS version
    
        Solution: Use CMD.EXE environment variable to extract
        DevStudio version number and build using it.
    

I got the idea from ZeroMQ's/hintjens' various repos.

------
nighthawk454
We've used this style in our commit messages for a few years, and it's been
great. We also only allow fast-forward merges of squashed commits for our
branching strategy.

    
    
      [ISSUE-ID]: Title
    
      [Problem]
      State problem and customer impact
    
      [Solution]
      Describe and justify solution
    
      [Test]
      Describe automated/manual testing

------
amenghra
Useful things to have in a commit message:

\- Test plan when there's no unit test (describes how to test that the patch
actually works).

\- Task ID (link to whatever is used to track tasks/bugs, as there's usually
more context there).

\- Blame rev when a patch fixes a bug, it's useful to know which commit
introduced the bug.

~~~
jononor
Blame rev is very useful for back/forward porting fixes.

------
dlandis
He mentions using the imperative mood for the subject line, but doesn't anyone
else think it makes more sense and sounds better to use the present tense,
e.g.

Opens the pod bay doors

Instead of

Open the pod bay doors

?

~~~
sleepychu
Maybe but it's nice to fit in with the existing imperative mood in the
automatic commits (Merge x into y)

You can read them in your head like this "Applying this commit will $MSG"

------
sandrot
just going to leave this here:
[http://stopwritingramblingcommitmessages.com](http://stopwritingramblingcommitmessages.com)

------
nimchimpsky
I can't believe believe people write essays on how to write a git commit
message.

It even includes an example of not including a full stop - I'm all for
examples, but sometimes they are not necessary.

Do other people not have actual work to do ?

~~~
jlgaddis
(I haven't written such an easy. Regardless...)

I can't believe people whine about ways I spend my time (or what I choose to
write about). It's not like you are being forced to read any of it.

~~~
nimchimpsky
its been submitted to a message board for comments, did you expect everything
to be positive ?

GIT commit message are hardly significant, unless you are doing some form of
automated release notes - and then you just follow whatever convention is
required.

------
sqldba
.

------
pmontra
The most important tip is "Use the body to explain what and why vs. how".

I'd also say: remove thw -m option from git and force people to open the
editor. Do not accept messages shorter than 3 lines, start the editor with a
template

    
    
      Title
    
      What changed and why it changed.

~~~
rosser
Dogmatism like "commit messages must be at least three lines" will result in
commit messages like:

    
    
      here's
      some
      code.
    

Concentrating on form over substance is myopic.

~~~
petepete
Totally agree. Using three lines of text to describe fixing a typo in the
comments or rewording/reformatting a block of text will just lead to an
unclear message.

