The "why" is THE thing that needs to go in the git commit message. Capturing "why" is the entire point of that message and slapping a link to some external (and eventually absent) resource is not a good substitute.
The "why" is THE thing that needs to go in the git commit message. Capturing "why" is the entire point of that message and slapping a link to some external (and eventually absent) resource is not a good substitute.
[PRJ-123] Changed blah to foo
Blah didn't handle the wangle flange properly in some cases, foo is a better fit for customer requirements.
The "why" that justifies the change, is already contained in the JIRA ticket PRJ-123 and explains exactly what the customer requirement was that necessitated the change. It will almost certainly contain a lot of detail that isn't relevant to the commit message, because that isn't the place to be documenting customer requirements, and probably relates to a number of other tickets. Perhaps the code itself might have a comment explaining the code change, if it's a non-obvious implementation, but otherwise the ticket is the best place for that information.
Additionally, if a change requires multiple commits, you don't want to be repeating the justifications for the entire feature in every commit message. It's redundant. But the commits will all be tied together by the ticket reference in the commit message.
I think the commit ought to describe the purpose of the change in terms of its result for the software's intended use. Feel free to hide the business/political drama behind a ticket number.
This gets down to a more fundamental tension. Are commit messages to communicate between developers? To communicate from developer to consumer? Or some kind of project manager golem? In practice, it is usually some constantly wandering attempt to be a blend of these.
That said, knowing the commit ID something is fixed in, so that the PM can track what build it emerges in is useful.
Through a git bisect, you find a commit that references JIRA, though your company uses Linear.
You sigh, and start reading the diff.
(Adapted from real life events)
> Additionally, if a change requires multiple commits, you don't want to be repeating the justifications for the entire feature in every commit message. It's redundant. But the commits will all be tied together by the ticket reference in the commit message.
Different commits do different things, so require different justifications. Here's a fictional example to demonstrate:
First commit:
[PRJ-123] Server: extract class Foo
In the next commit, we're going to need to re-use the foo logic from
class Bar. Extract new class Foo from Bar to make it available for
re-use.
Second commit on the same ticket [PRJ-123] Server: use Foo in Baz
The users of BazClient need to be able to see foo information in the
baz dialog. Include Foo in the data sent by class Baz in the server.
Side note: the user might not even know that they are looking at Foo and Baz, it might be called something else in the UI they are shown. Whether or not this needs to be included in the commit message depends on the situation.And later in a commit fixing a bug:
[PRJ-456] Server: check ID for null in Foo
When class Foo was extracted from Bar in commit deadbeef ([PRJ-123]
Server: extract class Foo, 2026-06-06), a null check for the field
ID got lost by accident.
Check the field ID for null in class Foo to avoid a
NullPointerException when a foo event is sent to Baz. [PRJ-123] Refactor Foo out from Bar
[PRJ-123] Include Foo data in BazClient
[PRJ-456] Null-guard on Foo ID to avoid data loss
Bug introduced in commit deadbeef
And then in PRJ-456, I'd also have the comment about bug introduced in commit deadbeef, and link the two JIRAs if it was significant, or just mention it in a comment for a minor fix.For me personally, nothing else in your commit messages adds value that can't be seen trivially from glancing at the changes.
It's fair that maybe such simple trivial changes don't deserve such a wordy commit message. But these are just fictional examples that I came up with on the spot. Refactorings, new features, and bugfixes can all have various levels of complexity.
A good commit message helps answer the "why?" questions first and foremost. If a diff is fairly large, pointing out the most important change can be useful. Explanations for non-trivial dataflow can sometimes not make sense in separate documentation, but still be relevant in a commit message.
Much of such issue tracking systems may be better in the repo in the first place. A Jira issue could just be a markdown file committed in the repo. A code review could just be commits of inline remarks/comments.
Maybe there is some value to slapping on a web interface on top of that data for ease of use, but as to where the data lives I'm leaning towards putting everything in repo.
It may be that my perspective is different because my work tends to be in "hard" foundational software (think OS components and programming language tool chains). It's not that customer requirements aren't a thing at all in that kind of work, but they tend to be far removed from the day-to-day and instead, mechanical sympathy rules supreme.
Commit messages need to focus on the software, not on the trappings of the process by which it evolves. Links to tickets can provide helpful context especially for bug fixes, but they belong in the commit message footer.
Your last paragraph is absolutely an anti-pattern at least in this work. If the implementation of a new feature is split over multiple changes, then surely there is something different and important to say about each of those changes. Does your split even make sense otherwise?
But as for the last point, many companies prefer constant integration of work in progress (perhaps with new functionally disabled) for development work that can take multiple weeks, rather than working entirely in a feature branch and introducing a massive change in one go, especially if it's required refactoring work to existing code. On such codebases, my commit frequency would typically be at least a couple of times per week, perhaps a couple a day in some cases.
So, while each commit will have a commit message explaining the change, none of those commits would be a sensible place to try to explain the justification for the work, something which I was already arguing shouldn't be in commit messages at all. The last point was an attempt to show that it makes even less sense to try to replicate the why of the feature requirement in the commit message at all. That is already documented in the ticketing system, the commit message should contain a summary of what changed, to aid a later developer trying to track down a bug.
From your third paragraph, it seems that we largely agree, you just disagree that the information about the ticket a change relates to is important enough for the subject line. If it was a URL link, I'd agree because they are long and messy, but honestly a JIRA reference like [PRJ-123] doesn't use much space and putting it on the subject line seems the best compromise to me, because I consider it mandatory. But if your company prefers a different policy, that's fine too - different companies don't all have to do the same thing.
FWIW, I've also worked in what you call '"hard" foundational software'. In fact, that's exactly where I was first exposed to this policy, recognised it was better than previous systems in previous companies for traceability, and later advocated it in other companies with smaller teams, and also use it myself on my one-man projects.
The data in the ticket system should be considered important as it's the primary interface through which developers, QA and design share information.
I can’t fathom why part of the deployment of the new system wasn’t to re-seed to the current ticket number or an easy-to-remember integer (hopefully via database, but also ok even if via a Selenium for loop to pull 19,999 tickets to burn the numbers in the new system).
1. Usually the commit message is often too short to capture the "why" adequately. 2. It is very beneficial to capture the why in one single source of truth, and that usually is not the Git commit message in a business context. Hate on Jira all you want, but if you capture the "why" there, you can add comments, view history, add rich context, link dependencies, add rich context, etc. Can't do that in a Git commit message.
Business (ie. $work) will dictate whatever it wants and that is what get used but for anything I personally have control over, everything goes in the repo itself to prevent platform lock-in. For example, github's been going downhilll lately but all those projects with their history in PRs, etc. now needs to exfiltrate all that data somehow.
The commit message is writen in retrospect and is written for someone with the code in front of them to explain why this change was made, and why it was done in this particular way.
If your commit message is too short then than is your problem right there. The easy fix is you taking five seconds out of your busy day to save an hour for you readers.
Have you seen how commit messages are written for git itself, or for the Linux kernel? Let me help you by linking the currently latest commit in the github mirror of git, it is not chosen to be particularly good or bad but is pretty representative of how git developers write commit messages: https://github.com/git/git/commit/b809304101
As you can see, without knowing much of the specifics of the code, we can get an idea why this change was made the way it was. There is a certain art to writing short and concise commit messages, but the same is true for code itself. Some, but comparably very little, practice is required.