DEV Community

loading...
Cover image for How to write a good commit message

How to write a good commit message

chrissiemhrk profile image Chrissie ・2 min read

A commit message is a short description of the changes you've made to a file added before committing the changes.

Good commit messages are important not only for others who you may be collaborating on the project but also for you, to keep track of all your commits and knowing exactly what changes where maybe during that particular commit.

Even if you're working on a personal project, I'd recommend that you start getting in the habit of writing good commit messages.

This is the format that I use most of the time (this may change depending on your preference or organization your working for):

type: subject

body (optional)

footer (optional)
Enter fullscreen mode Exit fullscreen mode

1. Type

  • feat - a new feature
  • fix - a bug fix
  • docs - changes in documentation
  • style - everything related to styling
  • refactor - code changes that neither fixes a bug or adds a feature
  • test - everything related to testing
  • chore - updating build tasks, package manager configs, etc

2. Subject

This contains a short description of the changes made. It shouldn't be greater than 50 characters, should begin with a capital letter and written in the imperative eg. Add instead of Added or Adds.

3. Body

The body is used to explain what changes you made and why you made them. Not all commits are complex enough that they need a body, especially if you are working on a personal project alone, and as such writing a body is optional.

A blank line between the body and the subject is required and each line should have no more than 72 characters.

4. Footer

The footer is also optional and mainly used when you are using an issue tracker to reference the issue ID.


Example of a good commit message used by Udacity student Udacity Git Commit Message Style Guide

feat: Summarize changes in around 50 characters or less

More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of the commit and the rest of the text as the body. The
blank line separating the summary from the body is critical (unless
you omit the body entirely); various tools like log, shortlog
and rebase can get confused if you run the two together.

Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how (the code explains that).
Are there side effects or other unintuitive consequences of this
change? Here's the place to explain to them.

Further paragraphs come after blank lines.

  • Bullet points are okay, too

  • Typically a hyphen or asterisk is used for the bullet, preceded
    by a single space, with blank lines in between, but conventions
    vary here

If you use an issue tracker, put references to them at the bottom,
like this:

Resolves: #123
See also: #456, #789



A more practical example:

docs: Fix typo in README.md

Discussion

pic
Editor guide
Collapse
devmount profile image
Andreas

Short and clear, thank you for this article!
I tend to use emojis for the type - it shows the type of the commit at first glance, e.g.:

➕ :heavy_plus_sign: when adding a file or implementing a feature
🔨 :hammer: when fixing a bug or issue
💚 :green_heart: when improving code or comments
⚡ :zap: when improving performance
📜 :scroll: when updating docs or readme
🔑 :key: when dealing with security
🔁 :repeat: when updating dependencies or data
✅ :white_check_mark: when a new release was built
👕 :shirt: when refactoring or removing linter warnings
❌ :x: when removing code or files

... and looks awesome in the commit history:

Collapse
maxiqboy profile image
Thinh Nguyen

Thanks for your tip!

Here is the web for other Git emoji ideas: gitmoji.carloscuesta.me/

For me, it looks too much to remember,

so I just use some emojis to keep it simple:

🎉 :tada: initial commit 🎉

🚀 :rocket: [Add] when implementing a new feature

🔨 :hammer: [Fix] when fixing a bug or issue

🎨 :art: [Refactor] when refactor/improving code

🚧 :construction: [WIP]

📝 :pencil: [Minor] Some small updates

Collapse
goodevilgenius profile image
Dan Jones

It is too much to remember. I use github.com/carloscuesta/gitmoji-cli so that I don't have to remember which emoji is used for which type. It's a git commit hook, so I just do git commit, and it interactively helps me pick the appropriate emoji, write my commit message, and then drops it into my editor to make changes as needed.

Thread Thread
nutriz profile image
Jérôme Gully

If you must use an additional tool to remember your emoji meaning, I bet other too are lost for the interpretation of the emoji, once the wow effect has passed, I think words are much easier and quicker to understand :)

Thread Thread
devmount profile image
Andreas

I almost always use both: emoji for recognizing the commit type at first glance and text for a clear and unambiguous description 👍🏻

Thread Thread
nutriz profile image
Jérôme Gully

yes but even for the commit type, I find a word more meaningful than an emoji (and new people on the project / people reading commits without being part of the project) don't need to learn what emoji corresponds to what :).

Thread Thread
devmount profile image
Andreas

You make using emojis sound like rocket science 😅 we're talking about little pictures with clear content. A hammer is for fixing something, a scroll is for something documentation related. There really isn't much to learn 🤷‍♂️

Collapse
devmount profile image
Andreas

My pleasure 😊
This is also a nice interpretation, in the end it's a matter of taste, I think.

Collapse
darkwiiplayer profile image
DarkWiiPlayer

I hate when people do stuff like this. It just looks confusing in the git log. Just use unicode emojis instead, they work everywhere.

BTW my favourite emojis for commit messages: 🎆🎊🎉😖💢😅 (I usually put them at the end of the commit message though)

Collapse
devmount profile image
Andreas

Thank you for this valuable addition. Most of the terminals / bash / consoles support way more than unicode emojis nowadays. So that shouldn't be a problem for most of us. Here is, what my git log looks like:

Thread Thread
darkwiiplayer profile image
DarkWiiPlayer

Unicode emojis are standardized though, while the :: notation is not.

Collapse
imjvictor98 profile image
João Victor

I never thought to use emojis for that LOL. THIS'LL HELP ME A LOT. 🤩

Collapse
devmount profile image
Andreas

Glad I could help 😊

Collapse
banji220 profile image
Banji

I think it would be better to write a complete post about the way you are using Emojis!
Keep it up ;)

Collapse
devmount profile image
Andreas

Thank you for this suggestion and the encouragement - I'll draft this to my list of post ideas 👍🏻

Thread Thread
banji220 profile image
Banji

Nice to hear that you found my suggestion cool.
I'm waiting for your amazing post.

Keep Moving Forward ツ

Code with 💛

🅑🅐🅝🅙🅘

Collapse
banji220 profile image
Banji

Wow, it looks so awesome.
Tnx for sharing your tips :)

Collapse
devmount profile image
Andreas

My pleasure 😊

Collapse
omgcheese profile image
Jin

That's pretty awesome and fun way to write commit message!

Collapse
devmount profile image
Andreas

Exactly what I experienced 👍🏻

Collapse
iamlukeamiller profile image
Luke Miller

I ALWAYS forget that emojis are valid in all kinds of spaces now. I often use them in debug console messages to make it visual and easy to search, but using them in this git commit message format is super handy. Thanks for the recommendation!

Collapse
devmount profile image
Andreas

You're very welcome, I'm glad it's useful for you 😊

Collapse
chrissiemhrk profile image
Chrissie Author

I've seen emojis being used in some projects but they always seemed intimidating to me, I'll have to look more into how to use them

Collapse
devmount profile image
Andreas

It needs a little time to getting used to it, but then you don't want to be without it anymore, I promise 😂

Collapse
karltaylor profile image
Karl Taylor

I LOVE THIS. I might even print it out and stick on my wall. Thankyou!

Collapse
devmount profile image
Andreas

You're welcome 😊

Collapse
developerkaren profile image
Karen Efereyan

Looks so cool.

Collapse
devmount profile image
Andreas

Thank You 😊

Collapse
rabbitzzc profile image
Collapse
sagar profile image
Sagar

I'm using git alias to create a beautiful commit message with emoji and my commit message structure looks like this.

[emoji] <type>(scope): <message>
Enter fullscreen mode Exit fullscreen mode

e.g.

🐞 FIX(pages): security issue fix on pages table
Enter fullscreen mode Exit fullscreen mode

Here is my .gitconfig

# Git Commit, Add all and Push — in one step.
cap = "!f() { git commit -m \"$@\"; }; f"
# NEW.
new = "!f() { git cap \"📦 NEW($1): $2\"; }; f"
# IMPROVE.
imp = "!f() { git cap \"👌 IMPROVE($1): $2\"; }; f"
# UPDATE.
up = "!f() { git cap \"✍🏻 UPDATE($1): $2\"; }; f"
# FIX.
fix = "!f() { git cap \"🐞 FIX($1): $2\"; }; f"
# RELEASE.
rlz = "!f() { git cap \"🚀 RELEASE($1): $2\"; }; f"
# DOC.
doc = "!f() { git cap \"📖 DOC($1): $2\"; }; f"
# TEST.
tst = "!f() { git cap \"🤖 TEST($1): $2\"; }; f"
# BREAKING CHANGE.
brk = "!f() { git cap \"‼️ BREAKING CHANGES($1): $2\"; }; f"
# REMOVE
remove = "!f() { git cap \"🗑 REMOVE($1): $2\"; }; f"
# REFACTOR
ref = "!f() { git cap \"♻️ REFACTOR($1): $2\"; }; f"
# INITIAL COMMIT
int = "!f() { git cap \"🎉 INITIAL COMMIT($1): $2\"; }; f"
Enter fullscreen mode Exit fullscreen mode
Collapse
ghostsquad profile image
Wes McNamee

probably a good place to share some things about this:

Here is the "conventional commit" pattern, which is super useful to be able to automatically extract information from your commits, such as for a ChangeLog.
conventionalcommits.org/en/v1.0.0/

This post has been around for a long time, and it's great!
chris.beams.io/posts/git-commit/

This tool helps you write conventional commits with emoji!!! It's super cool
github.com/vivaxy/gacp?ts=4

Collapse
suckup_de profile image
Lars Moelleken

You can share your git commit conventions in the team via e.g.:

add this into your "~/.gitconfig"-file

[commit]
  template = ~/.gitmessage

example: github.com/voku/dotfiles/blob/mast...

Collapse
wdhowe profile image
wdhowe

We store a file in the root of each project: .gitmessage

Then in the project's Contributing section in the Readme, we have:

Before contributing to this project, configure the commit template while in the project root:

git config commit.template .gitmessage

The contents of the gitmessage is:
jira/issue-####: Title of issue
Description of changes.

We then squash all commits on merge and enforce rebasing.

This makes for a very clean commit log like:

jira/issue-2: Do that
These are more changes.

jira/issue-1: Do this
These are the changes.

Collapse
suckup_de profile image
Lars Moelleken

How do you enforce rebasing?

Thread Thread
wdhowe profile image
wdhowe

It's a setting in GitLab per project.

Settings > General > Merge Requests.
Under Merge method, select "Fast-forward merge".

Description is: "No merge commits are created. Fast-forward merges only. When conflicts arise the user is given the option to rebase."

Collapse
jballanc profile image
Joshua Ballanco

Here's the super-concise commit message template that I've been using for years now (I've lost track of which blog post or comment I first picked it up from). I find it to be a helpful reminder, without inundating me with a wall of text every time I go to commit:

# If applied, this commit will...

# Why is this change being made?

# Provide links to any relevant tickets, URLs or other resources
Enter fullscreen mode Exit fullscreen mode
Collapse
huncyrus profile image
huncyrus

Nice article, and also I would like to add my opinion:

  • do not care of "title", the commit related ticket should have it.
  • the commit body should be 2-3 line only, if longer, then you supposed to split the ticket into smaller tasks (SOLID).
  • do not include emoji, markdown or anything, just simple text. Do not forget, not everyone has the same stack and could make pain to read whatever you did
  • Include related ticket or tickets

Example
MYPROJ-420 Updated vendor libraries (lodash, robot, d3) for xyz page.

Collapse
thinkverse profile image
Kim Hallberg

I wish my commits were that good, I did adopt this style a while back, also tried the gitmoji style for a while but, then I reverted back to simple - Add, Create, Remove, Delete titles. 😆

Might try this style of commits again, I really like how they look and the organization of them just feels better to me, also seems better for filtering with the colon as a separator. 🔥

Collapse
chrissiemhrk profile image
Chrissie Author

This is just one way to do it if you have no problem understanding your commits with the way you've been using then continue using that as long as it's clear and people won't have any trouble understanding the message.

Collapse
willvincent profile image
Will Vincent

This is pretty much how I've been doing commit messages for the past couple years, since adopting conventional commits and using standard version.

The only difference is my format is like this:
[type]([scope]): [Subject].

and then the optional body, which generally only gets filled out if it's a very large commit (usually a no-no) or is filled in automatically by github on squash & merge of a PR, or if there's a breaking change.

So for example:
feat(Foo): Adds the ability to bar.

fix(Bar): Bar should not prevent Foo.

BREAKING CHANGE: Bar now requires Baz.

Standard Version ingests these commits and automatically compiles a changelog, which we use as part of our deploy process. Result is an automagic changelog created on each production deploy that definitively captures all changes since the last deploy. It's glorious... and simple once you put the pieces in place.

Collapse
willvincent profile image
Will Vincent

The benefit of the scope being included is it will group all items by scope, alphabetically, in the changelog, and prefix each of the bulletpoints with that scope value so they're easy to spot.

Collapse
alessandrolia profile image
alessandrolia

We're always using a reference to our bug tracker system:

#{ticket no.} - {ticket title}

And we added a plugin to our bugtracker to "suggest" the correct commit message, which you can copy&paste into terminal or whatever git GUI in use ;)

Collapse
rbluena profile image
Rabii Luena

You can make your repository commitizen-friendly by using the following tool. github.com/commitizen/cz-cli

You can also read more about commitizen here. conventionalcommits.org/en/v1.0.0/

Great article @chrissie

Collapse
bonfacekilz profile image
the_savage

It's nice to add that this is just one convention of committing; check gnu.org/prep/standards/html_node/S... for an alternate widely used(especially in GNU projects) commit style. I normally default to that. Here's an example from some guix patch:

gnu: xorg-server: Fix CVE-2020-14347 via graft.

* gnu/packages/patches/xorg-server-CVE-2020-14347.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/xorg.scm (xorg-server/fixed): New variable.
(xorg-server)[replacement]: New field.
(xorg-server-wayland): Use package/inherit.
Collapse
corentinbettiol profile image
Corentin Bettiol

Thanks for this article!

We're using Bluejava's git commit guide, it's clear and self-explanatory :)

The main difference with your guidelines is that it replace "refactor/chore" with "maint" (as in maintainability).

Collapse
darkwiiplayer profile image
DarkWiiPlayer

Just my personal opinion, but I really hate having external references to things like issue trackers in the git history. They only work when viewed on a single platform but break at best or link to different information at worst when viewed from a different platform.

Collapse
egmontkob profile image
egmontkob

My favorite is the top utility within procps-ng. The commit messages are phrased so that each and every line of text (even the subject and even the last line of every paragraph) has the exact same width. No cheating with double spaces.

Another "favorite" of mine is ImageMagick. Many of their commit messages are a bare "...".

Collapse
harisharavindan profile image
Harish Aravindan

good one.

To enforce commit messages had written a script long back ( and a blog )
Validate the commit message, this will make sure we have the habit.
medium.com/@harisharavindan/server...

Collapse
jessekphillips profile image
Jesse Phillips

I use gitmoji.carloscuesta.me/

And I switch the footer and body, putting this issue system at higher importance.

Collapse
zoedreams profile image
☮️✝️☪️🕉☸️✡️☯️

IMPERATIVE MOOD • IMPERATIVE MOOD • IMPERATIVE MOOD

i agree with what you say. i have discovered ;) that D^V * 1/Cq * T/P = L; where D is how much description there needs to be, V is how verbose the author is C is the amount of lines of clear readable documented code, Y is the amount of time which the developer has been coding in that language, P is the affinity of penguins on a scale of 0 => 1 and L is the length of the commit message needed.

en.wikipedia.org/wiki/Imperative_mood
git-scm.com/book/en/v2/Distributed...

basically if it doesn't fit on my 60 x 50 char buffer window its prolly not all going to be read. lol

Collapse
iamlukeamiller profile image
Luke Miller

Honestly, commit messages are something I have by and large ignored in my development workflow (as a mostly solo Salesforce developer), but I can absolutely see the value in this. Hopefully shifting into a role at a consultancy soon, and I really think this will be a big assist.

Collapse
dabit_coder profile image
David Oliva Tirado

In my current company we use this method:

JiraTaskID - JiraTitle - Some description

It will result in something like:

1123 - Update dependencies for the users screen - Update package.json & yarn.lock.

Then we do a squash/rebase and it gives a really good looking tree :D

Collapse
uzairali001 profile image
Uzair Ali

Great! I always wanted to improve my commit messages but didn't know what I should do but now you gave me a pattern/standard to follow.
Thank you

Collapse
developerkaren profile image
Karen Efereyan

Hahaha. Thanks Chrissie

Collapse
sarahrosebuck profile image
Sarah Buckingham

This is so helpful - I'm terrible with commit messages and have not made it a priority to figure out a consistent method on what to write. Appreciate this sort of formula you have created!

Collapse
chrissiemhrk profile image
Chrissie Author

I didn't create it myself by the way, but you're welcome 😀

Collapse
glowkeeper profile image
Steve Huckle

Too much info', maybe? Personally, I dispense with the 'Type' stuff and infer that through branching, instead.

Collapse
andrewbaisden profile image
Andrew Baisden

Good article I will be levelling up my boring git commit messages from now on :)

Collapse
jakeerc profile image
Jakeer

Thanks, helpfull

Collapse
chrissiemhrk profile image
Chrissie Author

You're welcome :)

Collapse
helderburato profile image
Collapse
nguyenquangtin profile image
Tony Tin Nguyen

Thank you, short and very clear.

Collapse
maxiqboy profile image
Thinh Nguyen

Thank a lot!
That's exactly what I need these days!

Collapse
stefanoero profile image
Ero Stefano

Our branches include the ticket nr. A githook then adds the ticket nr to every commit.

Collapse
jadebeer profile image
Hannes de Beer 💥

You study at Udacity too eh. I thought I recognized that post :)