How I Write Source Control Commit Messages

rachelsoderberg profile image Rachel Soderberg Updated on ・4 min read

The concept of good messages to go along with your commits to source control seems to be one of those things that people either completely follow or completely drop the ball on. Fortunately my work right now is predominantly solo and I only have myself to blame if my commit messages are unhelpful, but I still try to follow a few rules to save the sanity of myself in the future. These are not industry rules, but merely my own standard that helps me maintain mine and my team's code base.

Rule #1: Good Messages Start With Good Story Cards

Some call them story cards, or tasks, or any number of other names for something that is a portion of work that must be completed from a less-manageable major task (aka an epic). Whatever you call them, many projects have some form of task list to work through and I leverage this list for my commit messages for later referencing. Several project management tools such as Jira or Mingle automatically assign cards to a number that increments as you go. The tool we use at my job unfortunately does no such thing, but I add a number to each card title manually to reap the same benefits. Each story card should have a basic title explaining what needs to happen. The description can go into more depth regarding the solution and other necessary information.

When I write up my commit messages, I start with the story card number for the work I'm submitting (you read that right - I try to keep it to one card per commit!) The beauty of providing the card number in your commit message is the ability to reference exactly what was done. If you need to go back to a week ago to figure out what changes were made that caused a new bug to crop up, you can look at the commit messages for the past week and see which cards were worked on and head over to your story board for further investigation.

Rule #2: Good Messages Are Descriptive

Consider for a moment that you've been tasked with going through the last month's commits of a fellow developer. Perhaps looking through the changes can lead you to what's causing this crazy new bug that just showed up. You bring up the source control manager and see something like this:
4/18/19 - committing stuff
4/15/19 - asdf
4/05/19 - before friday's meeting
4/04/19 - did stuff
4/01/19 - product card

Sure, you can look through each file that was changed in each commit to get an idea of what happened... but what if there was a better way? What if each source control message gave you a brief synopsis of the change that was done for that commit. Also, what if they were more frequent? A lot could have happened between April 5th and April 15th! I try to make a commit at least once a day; several times a day if I've been making a lot of significant changes in a short period of time.

The important part is to add some value to each commit message, whether you expect future-you or a coworker (or replacement) to read them or not. This simple act could save someone a great deal of time, giving them the ability to reference each major set of changes at a glance instead of needing to inspect each one.

Rule #3: Good Messages Explain What, Not How or Why

Another benefit to linking your commit messages to your storyboard by card numbers is the beauty of not having to repeat yourself. If your cards are written descriptively and show the steps taken to solve the problem, create the feature, etc., you don't need to write those things a second time in your source control because it can all be found if you follow the card number!

Your source control message should have some information in it though - I try to provide a sentence briefly explaining what changes were made. Some examples sentences could be "Added checklist for customer item selection" or "Removed discount button from main page". In the case of a card that spans over a longer period of time I will do several commits with a brief update of the work that happened in that span of time: "Implemented binding creation for Salesforce login feature".

If someone needs to trace back into the source control for the bug that showed up last week, they can get a birds eye view of the changes that went on in this period by reading the messages. If they see a message that sticks out, perhaps relating to the problem section of code, they can easily reference the number and check out the more detailed view in the related story card. The story card will provide them with the hows and whys of the changes that were made.

Good Messages Look Like...

So what do good source control commits look like? Here's a few examples of recent commits from my major project at work:
Card #213 - Updated formatting on Reports Form
Card #213 - Added Reports Form and first report to get and update all unprocessed orders
Card #208 - Updated query for discounts
Card #205 - Only requiring SOM_SalesOrderID in close/email dialog form
Card #204 - Moved SOM_UserDef5 and SOM_FOB updates ahead of SalesOrder XML creation

TLDR: When making source control commits, I try to keep my messages brief, descriptive, and maintain a regular formatting style. I also make an effort to keep one major change set or card per commit to avoid muddying up the change sets and messages.

Posted on by:

rachelsoderberg profile

Rachel Soderberg


I'm a Software Developer who loves working with C#.NET and Salesforce. In my free time I lift weights, do martial arts, and play video games.


markdown guide

Rule #3: Good Messages Explain What, Not How or Why

One thing the consider is what the benefit of the commit message will be long-term. In the future, when the context is no longer fresh in your team's mind, you might be debugging an issue or building code based on the code in the initial commit. For me, I'm much more often asking "why is this here"/"why is this like this" than "what does this do" (because I have the context of "what does this do" from reading the code itself).

I often find myself pleasantly surprised when I'm debugging an issue with some code, say to myself "what was I thinking", hit git blame/git show and immediately know the context.

I think the card number is definitely great, but I don't think a distilled explanation in a commit message is a a waste of time either. Another small nuance is that the commit message is written in your own voice with your own understanding of the problem, at the point in time that you've just written the code, so you're in a much better place to write a technical description of what you've just done (in my experience, finished code often deviates from the plan).

It does take longer to write the commit message, and I agree that it takes a lot to move a team to this practice, but I can personally vouch for the benefits!


I stumbled on this not long ago and I'll share here as I learned from it. Based on Angular's convention for commit messages. Here's the link

Basically like this:

<type>[optional scope]: <description>

[optional body]

[optional footer]

I've taken that knowledge and adapted it into what I do. The <type> part I am flexible with.


I've seen similar. I've used the karma git template which is this. This link has more detail though while I'll use to train with in the future. Thanks!


Be sure to check out the angular documentation which is a few clicks and a google doc away...


Sounds like a good convention! I'll look into the link later today, thanks!


I try to keep it to one card per commit!

I'd like to offer a deeper tip here. It is good practice to keep commits to functional units of work. A story might, and should, contain multiple commits.

Then your final commit of the story can contain a git message footer that links back to the story number.

Then you can also separate units of functional code apart from refractors and doc chores.

This will make code review and reviewing the git history a lot cleaner!

Great post! Commit messages are important on large projects with multiple team members.


First, thanks for sharing @rachelsoderberg ;)

Just came down here to write the same, I consider commits as the good old video game checkpoints.

Every time you hit a "safe place" where you would like to go back in case of something goes wrong, add a commit with a very descriptive message.

Your "future myself" (and code reviewers) will thank you a lot.

Further reading: pauline-vos.nl/atomic-commits/


Thank you! And that is a great point - a lot of times I commit every time I have finished a solid (hopefully working) portion of the card. Basically if I'm going to step away for a break and would regret losing what I built, I commit. If what I commit isn't working, I make sure to specify what doesn't work and why.


I would urge against commiting incomplete code. It really is a matter of opinion and process but for my team of 12 working on a large project keeping our git history clean is really helpful.

Some more tips to consider:

If you need to port code to another machine to continue working you can create a patch file:

git diff > patchfile
git apply patchfile

Or, if you do commit a temporary commit you could also squash the commits together using interactive rebase

git rebase -i HEAD~2


Great post, and one that more people need to read (and I need to adhere to more often). It's so easy to get lazy. Also, I think what I've noticed with myself and others is sometimes a commit message or commit includes far more than what's in the actual changes which can be problematic.


Thanks for triggering a discussion on a topic that deserves it and is very important.

I find that this article would gain from being refactored from a "this is what good commit is" to "this is how I commit".

Many of the things it recommends are far from consensual or standard, as pointed out by several comments. Similarly, the examples lack several features which are often considered as required for good commit messages.

As a consequence I think it would be more helpful for young programmers and for the community if it took a less normative approach, and rather a more descriptive one.


You make a good point, I am one of those young developers and probably made the article name a little too "absolute" as in everyone does them this way, rather than implying that it's my understanding of them.

I'm curious too - if you don't mind, what features did I miss that would be considered required for good commit messages?

Thanks for the comment, I always appreciate constructive criticism & feedback!


I am glad that you are receiving my comment positively!

It would probably take a whole blog post to answer your question, but I guess what comes closest to my opinion is this: chris.beams.io/posts/git-commit/

Best of luck for the start of your career!

Thanks - and thank you for the link! That will be good reading, I appreciate it.


Prepend commits with the file or component which it is affecting.

Readme: add install instructions


In git, there are commands to see what files a commit changed - to me, prepending files names seems unnecessary


I agree with the component / subsystem - the file is just a special case of that (of a very small component).


We did this at my last job as well. Either the filename or if it's multiple the source of the changes. It makes for a much easier to read git history / merge request.


Visual Stuido Team Explorer shows them as well, but this makes sense for ones that dont!


Here are the rules that I did save from one of the sources some time ago.

  • Separate subject from body with a blank line
  • Limit the subject line to 50 characters
  • Capitalize the subject line
  • Do not end the subject line with a period
  • Use the imperative mood in the subject line
  • Wrap the body at 72 characters
  • Use the body to explain what and why vs. how

I'd recommend against writing the card/issue number in the first line. It's the summary line and IMO it takes away precious space I'd rather use for a good summary. I put the issue number in the last line of the message. We are using gitlab and I can easily search for it in the GUI if that is necessary.


This is great! Commit messages are one of those weird parts of the development cycle that feel like they're just some boring, but necessary admin task. Having some guidelines (and enforced templates) help, but your article does a grand job of showing what bad and good messages look like and why the latter is important.

I also agree with Kyle's comment about context, but then you can also add a little more detail in the commit body for that where it's needed.


You also only want to change what you say is changing. I've pushed for using gitmoji in every commit. The goal is to help review what the changes are supposed to do and make it fun to try and craft a commit to use a specific emoji.

Some of them should never make it to mainline though.


Have you looked at Commitizen? I find it useful for prompting me to write better commit messages.


I havent, but I'll certainly check it out later today! Thanks for the tip


Great examples! I do much the same, but branch by card number and do descriptions with each commit, but I like your way better. If a merge gets squashed it still carries the commit messages


Great post! It pretty much explains the way my company does commits, though I think we all need to work on committing more frequent, smaller bits that can easily be explained by a simple message.


When writing commit subjects I found a good tip saying to start a sentence with "If you applied this commit then it would..." then use the rest of the sentence as the subject line.


That is a brilliant tip! I might just have to steal that and add it to how I currently do them. Thanks for sharing!

Sloan, the sloth mascot Comment marked as low quality/non-constructive by the community View code of conduct

The beauty of providing the card number in your commit message is the ability to reference exactly what was done.

That's a noob mistake to rely on your issue tracker. You can add a reference but the commit should be self-sufficient. If your issue tracker is replaced—and not archived—you will be left with a diff and the message body.


I feel like your comment could have been just as effective without calling me a noob to start. Thanks for the comment though.


Aren't we forever noobs being a software dev?

ha, you're probably right. But we become less noob at some things as we learn from our mistakes (errr... experiences?)

In dev world mistakes are experiences as much as bugs are features.
(This one is growing into being my favorite topic on devto)


I was just warning you because I used to be that noob and it sure was embarrassing to not have foreseen the dependency problem. You will have to experience it for yourself.

I feel like

triggered :)

See that was a more effective argument/starting point than just calling it a noob mistake. Experience, be it my own or someone else's, is a good place to learn.

What did the dependency issue end up being? Right now my cards arent physically linked to the source control, so I am manually using the numbers as a sort of reference point. (We use Microsoft Planner for our cards and VS for source control)


I have yet to see a development organization that would be willing to copy the full context of the ticket/card into a commit message. I'm sure they exist, but based on my own experience I'd think they are a minority. So linking the card/ticket absolutely provides greater context into what the change was trying to achieve, even if the commit itself is nicely squashed and written up.

And yes, if you switch ticket systems you will likely lose the ability to automatically link to those cards. Having done this several times, I've found that it is generally possible to import into the system with the same id/number as the original system. You lose the automatic linking, since each system seems to have a different pattern it expects the number in, but when you see #12345 in a ticket you can still pop open your ticket system and find [12345] or XYZ-12345. The key is whether your org sees the value and finds it worth the extra investment during the migration from ticket system A to B.

In my career, I've seen several source control migrations where we had to make the same call. Is it worth migrating so we keep the original commit messages or should we just start clean with a single "All the changes up to now" commit?


Whenever possible go for the migration. I work on a product with a 15-years-history and sometimes it helps to know that a feature/"behaviour" was introduced 10 years ago ("it has always been like this") rather than 15 months ago. Good commit messages are really helpful, of course.


copy the full context of the ticket/card into a commit message

You probably misunderstood me. I just want to deter messages like "feat: close #235".

Is it worth migrating so we keep the original commit messages or should we just start clean with a single "All the changes up to now" commit?

If you really care you will have to rewrite the history.


An issue tracker is an essential tool in development. You should be able to rely on its existence for as long as the history of the source code is relevant. Eventually tools are replaced, but so are commits relegated to history by then.


Sadly it happens. My last org went through a few kinds of issue trackers. Some of which had licences and would cost money to keep around, so they were ditched. Adding a reference can be super useful, but I feel the commit should speak for itself.

Anyways we ended up using gitlab's issue tracking features, which are quite nice as well.


…but so are commits relegated to history by then.

It seems that you are not using log and blame as much as I do.


Pretty sure the post went on to say that your message should be descriptive by itself too. So it doesn’t sound like they were suggesting we “rely” on the issue tracker, just utilize it.


I find the opposite better. Closing the cards with the commit or merge SHA:
Fixed in c678ads...etc.


I would agree if I wasn't lazy and relied on the auto closing feature of the issue trackers that are properly linked to the repository.