
Conventional Commits: A specification for structured commit messages - BenjaminCoe
https://conventionalcommits.org/
======
jevgeni
Imagine the following future:

“Have you linted and unit tested your commit message?”

“Junior Developer wanted. 10 years of Conventional Commits experience
required.”

“Download Conventionalizer! Now you can write Conventional Commits in plain
English, having all the syntax automatically generated! (node, erlang OTP and
Jerry’s pre-alpha TensorFlow binding library required. Windows support coming
soon.)”

Something tells me the authors are hard at work solving a problem nobody needs
solving.

~~~
skrebbel
On come on, this entire "spec" can be summarized in two sentences. It can be
validated with a 13 character regex.

I share some of your sentiment though: I feel like the biggest reason to
enforce a style like this is not for "machine readable commit messages" (I
mean, _why?_ ), but to encourage people to split refactors and features in
separate commits. This makes it easier to understand what's going on later.

I think this site should've begun with that, and left the spec as a footnote.

~~~
wincent
> Why?

The machine-readable part is useful for generating changelogs (eg. broken out
by type) or implementing semver (eg. detecting breaking changes).

~~~
hakre
but isn't it an antipattern to generate change-logs from commit subject lines?

~~~
ratherbefuddled
Of course not. How else would you do it?

~~~
dchest
Make a human read the commit history (or tickets) and summarize changes in the
language useful for users, not for developers.

~~~
Vinnl
Exactly. I can read commit messages myself, but there's a lot of stuff in
there that's not relevant to me as a consumer - e.g. refactorings, cleanups,
etc.

------
house9-2
> feat: a commit of the type feat introduces a new feature to the codebase

instead of 'feat:', why not 'feature:'?

I dislike partial abbreviation because it is confusing; yes doc for document
and max for maximum make sense but in this case feat is literally a different
word?

~~~
ChristianBundy
And while we're at it, why don't we just use full sentences?

Before:

> feat: allow provided config object to extend other configs

After

> Add option for config object to extend other configs

I know this isn't the point of changelogs, but I've been using the verbs from
KeepAChangelog to start my commit messages and it's been going well so far.

> Add template preview to status page

> Change textarea to increase height on `:focus`

> Remove deprecated CLI flags

> Fix margin styles causing layout problems

~~~
YorickPeterse
I agree that full sentences (e.g. like Email subjects or blog post titles) are
better. Tagging commits with feature/bug/etc is not particularly useful, as
more often than not the line between feature, bug, etc is blurry. At times it
can also be unclear what tag to use, leading to arbitrary choices. For
example: is a performance improvement a feature, or a bug fix? The tags also
add no value when reading commit messages.

Setting that aside, the conventional commit "standard"
([https://xkcd.com/927/](https://xkcd.com/927/)) doesn't focus on what I think
is the most important aspect of a commit: a good commit subject and message.
In fact, prefixing the subject line with certain tags limits the amount of
characters you have for writing the message; assuming you want to stick with
the usual 50 character limit.

~~~
JMTQp8lwXL
> feature/bug/etc is not particularly useful

It's useful for automatically determining the next semantic release version by
inspecting the commit history alone.

fix: <\-- patch

feat: <\-- minor

breaking: <\-- major

~~~
bluejekyll
So why not just use patch, minor, major? Then we don’t even need the
indirection.

Some fixes will require breaking changes. Fixes can be part of the message
with the issue #, etc.

~~~
boudin
In this case you suppose to add a ! after fix: fix! By using patch, minor and
major you lose some information (the purpose of the commit)

------
kazinator
I'm sticking to the GNU ChangeLog format, thanks.

[https://www.gnu.org/prep/standards/html_node/Change-
Logs.htm...](https://www.gnu.org/prep/standards/html_node/Change-
Logs.html#Change-Logs)

This widely used format gives details about what is being done to each
function.

This was designed to be used in a ChangeLog file, so it has to be adopted for
repository use. We don't have to record the date and name, since that is in
the commit meta-data. WE write a commit title, and then the ChangeLog entry
becomes the details placed after the blank line. That entry is mandatory: no
title-only commits! There can be one or more discussion paragraphs between the
title and the ChangeLog entry. We know that these paragraphs aren't ChangeLog
entry material because they don't begin with the asterisk.

Like this:
[http://www.kylheku.com/cgit/txr/commit/?id=b2739251281d7f6ef...](http://www.kylheku.com/cgit/txr/commit/?id=b2739251281d7f6ef4d30164101bdf2a8d537a72)

~~~
epage
Personally, I feel like this style puts the focus on what rather than the why.
I also dislike that it seems to be centered on multiple changes in one commit.

------
AndrewHampton
We've been following conventional commits for our front end code for the last
year or so at my work. In other repositories, we've loosely followed the keep
a change log conventions. I find conventional commits great when your
repository will produce a package to be consumed by others. For example,
conventional commits for our shared JS code helps us produce great change logs
and helps us easily follow semver for the NPM packages our other applications
use.

However, I don't find it that useful in the the final applications, even
counter productive, since it typically will take up quite a bit of space in
the commit title. Many of our front end devs completely ignore title length
conventions now.

~~~
jackcodes
Why don’t they put the additional information in the body of the commit?

I see this in nearly every company I go to - everyone rushing to skip over
adding anything useful to the permanent log by using git commit -m rather than
a plain got commit.

~~~
_asummers
This is the place where (mentioned elsewhere in this thread) things like issue
tracker links and other context can and _should_ go if you're using something
like CC.

------
notmyfuture
For use cases where this level of rigour is desired, it would be nice to have
real separate metadata vs. convention. Doing this by convention is unreliable.

~~~
wincent
You can get a basic level of enforcement for free by turning on the "Semantic
Pull Requests" bot that will let you know when you forget the type (or use an
invalid one):

[https://github.com/probot/semantic-pull-
requests](https://github.com/probot/semantic-pull-requests)

It obviously won't catch your mistake if you forget to mark a breaking change
as breaking, but it's a start.

------
Aeolun
I don’t think this is so much to make your commit messages better, as it is to
make sure that all of them can be automatically processed into changelog and
semver updates.

~~~
_asummers
This is the way to think about it. It's concise enough and has tooling in
enough languages to where generating the changelog from the commit messages is
just a CI step, but it doesn't offer much more. I like and have used
Conventional Commits for several years, but the goal is just tooling around
telling others what changed outside of reading the git log, e.g. PMs who want
an HTML artifact.

------
andrewprock
This strikes me as quintessential bike shedding, process for the sake of
process.

------
epage
At $DAYJOB, we organically switched from not having any formal style to having
an internal formal style. People seemed to want the benefits of tooling
integration and clearer communication.

Right now, we are switching SCM's and are looking at adopting Conventional to
replace our internal style. I've already started using Conventional and have
really appreciated it. It makes it fast and succinct (remember, line length
"requirements" in git) to get the information you need even in one-line logs.
Also, it makes CHANGELOG maintenance easier, whether using an automated tool
or doing it by-hand.

Not happy with the other ones, I've created my own commit style validation
tool, committed [0] and have deployed it on my open source projects. Like code
style enforcement in CI, I like delegating this to a tool since it makes the
requirement very clear for contributors.

The one thing I'm disappointed with with Conventional is that they did not
follow git conventions for multi-line trailers.

[0] [https://github.com/crate-ci/committed](https://github.com/crate-
ci/committed)

~~~
mgoblu3
Similar experience here. On really big teams sure, you can bike shed the
format a ton, but they’re all relatively close enough but CC has some good
tooling so we just ran with it. Results have been fine, didn’t waste a bunch
of time debating it.

Haven’t figured out a good way to integrate co-authors easily with it though.

~~~
epage
Wouldn't Co-Authors just be a footer/trailer?

------
rinchik
Isn't wording a bit off? "scope" should describe what the commit __DOES __,
not what you are personally DOING, and not what you were intended to DO.

"body", optionally, describes WHY.

Also it feels like more of a convention for a personal project with optional
C(I|D) automation prerequisites. In a team there should be a clear and
emphasized place for the issue tracking info (ticket number, task id etc etc)

~~~
GordonS
I quite like the idea of `scope` for large, multi-component projects, so you
can tell instantly from the commit message what component has been changed.

------
abtinf
I’ve found the commit message guidelines at [https://git-
scm.com/book/en/v2/Distributed-Git-Contributing-...](https://git-
scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project) to very helpful
for clarity.

“ The last thing to keep in mind is the commit message. Getting in the habit
of creating quality commit messages makes using and collaborating with Git a
lot easier. As a general rule, your messages should start with a single line
that’s no more than about 50 characters and that describes the changeset
concisely, followed by a blank line, followed by a more detailed explanation.
The Git project requires that the more detailed explanation include your
motivation for the change and contrast its implementation with previous
behavior — this is a good guideline to follow. Write your commit message in
the imperative: "Fix bug" and not "Fixed bug" or "Fixes bug."”

~~~
nirvdrum
50 chars seems pretty arbitrary to me. I'd rather have a useful commit
message. I've seen some pretty contorted messages conveying no real info in
order to meet an imaginary character limit.

~~~
hakre
the 50 chars is for the subject. the commit message (body) has no character
limit (apart from a character limit per line).

~~~
nirvdrum
Right. But that's the limit I don't get. If I always have to view the expanded
set of commit messages to understand anything about the commit, what's the
value in a short subject? And why 50 chars? That's even more restrictive than
the normal 72/76/80 chars.

~~~
GordonS
I think a limit is helpful to keep the subject line short, but I _frequently_
(like, daily) struggle to fit useful messages into only 50 chars. Personally,
I find 72 chars to be the sweet spot.

I wish GitHub or Azure DevOps made this configurable (because I use them) -
anyone know if any other hosted git systems have this as a configurable
option?

~~~
nirvdrum
I'm in favor of a team being able to set a limit if they'd like and tools
adapting. Personally, I'd rather a 90 char commit message that conveys useful
info than a contorted message intended to fit in 1/3 the size of an SMS
message.

------
t0astbread
I do something like this but for branch names. This spec recommends a squash-
merge workflow to turn branches into commits before merge. Why would I wanna
do that? It seems like throwing away a lot of detail unnecessarily.

------
inlined
SemVer is generally good practice but I don’t like promotion to religion. For
example, during the pre-release of the firebase-functions SDK we shifted
SemVer by one: 0.2.1 was a feature addition from 0.2.0 and a breaking change
from 0.1.

Similarly there are rare cases where I’ve swept breaking changes under the rug
because they were severe bug or security fixes that affected a corner case
unlikely to be seen in the wild.

~~~
hyperpape
I believe the first one is semver: before 1.0, anything can change at any
time. [https://semver.org/](https://semver.org/)

------
zoomablemind
Commit messages are just that - an additional communication tool. As long as
any format helps keep the understanding within a team clear with a minimum of
overhead, so be it.

After all the commit message is secondary to the actual code committed.

I'm sure everyone can share an episode when a nicely worded commit had to be
followed up with an ugly 'Fix a typo' message.

The most practical convention is the one that's automated to some degree, for
example, issue/feature tag auto-linking or some template driven messages.
Either way the message should not become an ultimate hoop to jump before the
actual commit and one more thing to 'maintain', the code should be the focus.

In my experience, a commit message describing the committed behavior (even
when intended) helps tie the code to the overall scope. In case when it's a
bugfix, it still must be tied to a correct expected behavior.

So in some sense a commit message could serve as an auxilliary level of unit
testing. Of course, I'd rather put an effort to enforce the actual practice of
unit testing over structuring the commit messages.

~~~
pantalaimon
> I'm sure everyone can share an episode when a nicely worded commit had to be
> followed up with an ugly 'Fix a typo' message.

There is `git commit --fixup` and `git rebase -i --autosquash` for that ;)

------
Karupan
We’ve found conventional commits useful in our mono repo. Instead of letting
the authors deal with versioning (which sometimes breaks dependencies), our
build pipeline determines the semver from the commit messages. This has made
it easier to deal with releases for around two dozen packages by developers
spread across three different countries.

------
eyegor
> _When you used a type not of the spec, e.g. feet instead of feat_

This actually had me laughing quite a bit. Because of my love for dad jokes,
here are some less conventional commits:

"fete" : adding holiday support

"braking change" : a change of pace

"nix" : removing a featute

"suffix" : adding a nice to have

------
leerob
Conventional commits pair nicely with a Lerna monorepo when deploying multiple
JS packages at once. Auto-generated changelogs and automatic semver for
packages. It's worked well for us over the past year.

[https://github.com/lerna/lerna/blob/master/commands/version/...](https://github.com/lerna/lerna/blob/master/commands/version/README.md#--conventional-
commits)

------
wwqrd
lost me at “feat”

~~~
_asummers
I would rather shorten the standard tags around it than have to shorten the 80
char short commit message. Typically tooling allows you to add your own tags
(e.g. imp: for improvement) so you could add feature, but I find myself
needing those extra few characters more often than not

------
crististm
I like best the irony of "refactor!". A breaking change with a title meaning
there should not be semantic changes in the code...

------
sime2009
I have to admit that in the GitHub and PR era I rarely look at individual
commits or their messages. I look at whole PRs.

------
vemv
prefixes such as "fix: " are better expressed at the bottom of the commit
message body.

They are metadata, and as such they shouldn't take more attention than the
actual data.

This matters when you are in a bug hunt in production - you want to find the
culprit commit as efficiently as possible, without distractions.

------
w_t_payne
I have a system that creates commit messages automatically. The commit
messages themselves are YAML so that they can contain various bits of metadata
- current task id, timestamps for oldest/newest known builds associated with
that task etc...

------
dajohnson89
maybe it's just me, but things like this sap half the fun out of development.

------
mohaba
feat of strength or great strength of feet?

~~~
ledauphin
...don't follow.

------
boring_twenties
This would be better if it was called the Committer Convenant.

