Conventional Commits encourages focus on the wrong things
Posted by jsve 4 days ago
Comments
Comment by hn_throwaway_99 4 days ago
I'm not saying that conventional commits are God's given best way to structure a commit message, but they are a defined structure, and I find it much more effective and important that some expectations be set around commit messages, and I think conventional commits are as good as anything.
Like the author is making a big deal that they think scope is more important than type. I may tend to agree, but I think the difference between "fix(compiler)" and "compiler fix" is not exactly a hill I'd be willing to die on.
The tech industry has tons of things that became standards even if they weren't optimal. E.g. if one were starting from scratch I think any sane person would argue JSON should support comments (sorry but Douglas Crawford's rationale for not including comments never made sense to me), better defined numeric formats, etc. But it was better in many contexts than what came before it, so it became the standard. I could believe that there is some other format that differs a bit from conventional commits that is a little better, but not really better enough to want a whole other competing way of structuring comments.
Comment by olzhasar 4 days ago
Comment by bloppe 4 days ago
Comment by xigoi 4 days ago
Comment by steveklabnik 4 days ago
Comment by mattrb 3 days ago
Comment by Mawr 4 days ago
Comment by monooso 3 days ago
I can't see any suggestion on the CC site [^1] that it "solve[s] the core issue of the poor commit messages problem."
Rather, it's explicitly described as "a specification for adding human and machine readable meaning to commit messages."
I'd say it accomplishes that modest goal.
Comment by SOLAR_FIELDS 4 days ago
This comment assumes you are picking between a conventional commit message or something better. But the reality is you are almost always picking between a conventional commit and Nothing.
Comment by Guvante 4 days ago
Tabs vs spaces don't matter they are equivalent.
But consistency is only better when it is an improvement.
It is fundamentally important that convential commit is better for adopting it to be an improvement.
After all in your example wasting the first four characters of your commits with poop would objectively reduce the quality of your commit history, whether or not it was consistent.
Comment by SOLAR_FIELDS 3 days ago
Absolutely! Which means we can also agree that conventional commit is objectively better than No System For Their Commits At All, which is what 99.9% of people are actually choosing between when evaluating conventional commit. They aren’t looking at conventional commit vs Some Better Way, they are looking at “we have no standardization of commit messages” vs “we have standardization of commit messages”.
For the 0.1% people for whom that’s not good enough, one hundred percent agree that these people should be pursuing better solutions.
Comment by rablackburn 4 days ago
Just to nitpick (because what else is this thread about? :))
They aren't equivalent! Tabs carry more semantic information than spaces. 1 Tab character == 1 Level of nesting
Space-based systems _can_ provide the equivalent semantic information if they are 100% consistent.
...but part of the argument in favor of spaces is that they allow an escape hatch of the strict indentation in order to allow pleasing visual alignments.
Comment by bfeynman 4 days ago
Comment by Guvante 4 days ago
In what context does wasting your first characters on fix vs feat matter?
PRs are going to have an explanation that has way more detail than necessary to figure that out quickly.
One lines tend to be (for me) in a situation where the difference is immaterial. If I am rapid firing through history I need to know what you did not why you did it.
Again I am not claiming that these are bad or even that they aren't good.
I am specifically disagreeing that any change is automatically good, that isn't true.
Comment by Merovius 4 days ago
I do not want to contribute to a project using conventional commits. I have consistently found, that I am unable to decide what the "type" of a commit even is and I feel unnaturally caged in into how I would split up commits, by having them be restricted to types (it doesn't help that the conventional commits I've seen appear to decide the type by fair dice roll).
Discouraging contributions does not "undoubtedly improve contribution semantics".
Comment by shimman 3 days ago
Comment by sharts 3 days ago
Comment by yencabulator 2 days ago
Comment by markbao 4 days ago
The claim is that Conventional Commits are good enough and standardized enough that having another structure isn’t really worth it. But “worth it” is subjective. I’d say that if you are making commits and reading PRs every work day, and the conventional commits format causes a little bit of friction, that friction can add up. Having another option other than seeing conventional commits as a law of nature gives options for teams who prefer it. (Most teams aren’t generating changelogs anyway.)
Comment by hn_throwaway_99 3 days ago
JSON was definitely a huge improvement in simplicity and readability compared to XML for many contexts. Similarly REST a much better option than SOAP (and all of these are examples of the general over-engineered, design-by-committee architectures that came out of the late 90s/early 00s - see also the original EJB spec - before a larger trend towards simplicity and ease of use won out).
But it this case, a lot of the differences just feel like potayto/potahto, i.e. minor stylistic preferences. And I have been in jobs where more than 50% of my time was doing code reviews, and while often there were e.g. some linter rules or whatever that I found suboptimal, it was a lot easier to just go with it than waste the energy to have the battle over why I think for loops are actually OK.
Comment by theptip 4 days ago
- scope is important: true, but isn’t that derivable from the commit contents? An important sanity check on a diff is to look at the paths touched. (A “test” diff should not modify prod auth code.) but if you want to see this from —oneline, sure, I think feat(auth): is better than feat:
- wrong audience: I don’t agree. feat commits _should_ actually describe the product-facing changes. You _should_ curate a nice stack with your no-op refactor changes first, then your small new feature change atop. This is the most helpful thing to include in a diff comment. You should put anything technical in comments so they are not lost, “why I chose algorithm X” belongs in a comment or DECISIONS.md. These are all tedious things that only psychos bother doing in a commit history at a fast moving company, but on OSS projects I think it’s much more important to stash context in the commit messages.
Comment by xena 4 days ago
Comment by BoingBoomTschak 4 days ago
Comment by beart 2 days ago
Comment by amadeuspagel 4 days ago
The big deal is not that scope is more important then type, the big deal is that natural language allows you to formulate things to emphasize whatever you consider important, and by forcing everything into a specific format this information is lost. There's a reason we have formats like markdown and plaintext, not just JSON.
Comment by hn_throwaway_99 3 days ago
Comment by scuderiaseb 4 days ago
Edit: forgot the link if anyone’s interested https://json5.org/
Comment by hn_throwaway_99 3 days ago
Comment by beart 2 days ago
Comment by daveisfera 1 day ago
Comment by stefan_ 4 days ago
Reminds me of the "scrum master" adjacent folks who could never cut it writing code and then branched into all kinds of things like "Git Flow" when having never understood Git to begin with. Peak bikeshed territory.
Comment by SoftTalker 4 days ago
Comment by soraminazuki 3 days ago
Comment by npstr 4 days ago
Comment by ajuc 4 days ago
One letter variables are supposed to be used in scopes that fit on the screen completely. You might as well search for "for"
TL; DR: it's on purpose.
Comment by SoftTalker 3 days ago
Exactly, and ideally in less space than that. If you have something like:
for (i=0; i<10; i++) {
foo(i);
bar(i);
}
There is no point in using a "descriptive" name for the index. It's completely obvious what's going on. Anything more verbose would just hamper readability.Comment by xorcist 3 days ago
Comment by nemetroid 4 days ago
Comment by yolkedgeek 4 days ago
Comment by compel2160 4 days ago
Comment by accrual 4 days ago
Comment by compel2160 4 days ago
Comment by rmunn 4 days ago
#inst "1985-04-12T23:20:50.52Z" = an instant / timestamp in RFC 3339 format
#uuid "f81d4fae-7dec-11d0-a765-00a0c91e6bf6" = a GUID/UUID
More tags could be defined by the standard later, because the entire unprefixed namespace is reserved. But just having a well-defined way to represent timestamps and UUIDs is an immense win over JSON, where you have to somehow know (based on what you were expecting to receive) that this string should be parsed as a timestamp or a GUID.
Also, user-defined tags will often be used to represent a class:
#myapp/Person {:first "Fred" :last "Mertz"}
Again, no need to know (based on what you were expecting) that this particular object is an instance of Person; the data transfer format tells you what class it is. JSON has to add a field, and what field it is will vary from application to application so it's usually not possible to write a universal parser. One server might generate { "__type": "Person", "first": "Fred", "last": "Mertz } while another one does { "$$class": "Person", "first": "Fred", "last": "Mertz }, for example.
EDN also has syntax defined for sets, but that's a smaller win over JSON, because it's not often necessary to declare that something is a set. Still, there are times it's helpful; it's certainly not a bad thing to have a set syntax.
Also, EDN has comments built in to the system. Two kinds, one line-based comment (useful for actual comments, e.g. when you use EDN as a config format), and one that comments out the next thing in the file (useful for temporarily commenting out an entire section with a single token, or for removing ONE item temporarily from a list that's all on the same line so line-based comments are difficult). Because Douglas Crockford didn't envision JSON as being used for config, he forbade comments in JSON, and people have been coming up with competing proposals for putting comments back in ever since. (Thankfully, nearly all the proposals interoperate, because all of them sensibly use Javascript comment syntax, so it doesn't matter if the file is JSONC or HuJSON or JSON5, the comment syntax is the same).
But the biggest win for EDN is tags, which can convey type information outside the data structure. JSON has to use something inside the data structure to convey type information, and there's always that small chance that the name chosen (__type or $$class or whatever) will collide with a property of the actual object that was supposed to be serialized.
Comment by compel2160 4 days ago
I also wonder if atoms can be reduced for low-bandwidth transmission. Naïvly, you could just prepend a lookup table for multiple-use atoms.
I guess it seems more like niche, additional features when GGP seemed to be claiming a big step up.
Comment by mook 4 days ago
Comment by rmunn 4 days ago
Actually, https://github.com/edn-format/edn says "It is envisioned that a reader implementation will allow clients to register handlers for specific tags. Upon encountering a tag, the reader will first read the next element (which may itself be or comprise other tagged elements), then pass the result to the corresponding handler for further interpretation, and the result of the handler will be the data value yielded by the tag + tagged element, i.e. reading a tag and tagged element yields one value. This value is the value to be returned to the program and is not further interpreted as edn data by the reader."
So if the client is specifying the handlers, then it's up to the client's handler implementation to sanitize the incoming data before instantiating the objects. And since the client supplies the list of handlers, the only tags that will be handled are ones the client was expecting. Assuming sanitizing the incoming data before instantiating objects is done correctly, I don't see any way for that to become a security issue.
Comment by yifanl 4 days ago
Comment by Groxx 4 days ago
though I do wish more editors had some kind of "ignore the spacing, display it semantically like [this]" and just let you insert whatever you wanted, converted to whatever is nearby, and didn't touch lines you didn't create. there's no reason to even have the debate or care about inconsistencies, you can essentially always* convert between them losslessly in terms of behavior.
Comment by chrisweekly 4 days ago
Comment by Terr_ 4 days ago
Comment by Groxx 4 days ago
as a bonus, this could also make `goto fail;` errors more obvious.
Comment by beart 2 days ago
Comment by masfuerte 4 days ago
Comment by SoftTalker 4 days ago
Crockford.
Comment by hexasquid 4 days ago
Comment by mmcnl 4 days ago
Comment by Izkata 4 days ago
Comment by ajuc 4 days ago
Comment by theptip 4 days ago
Comment by ralferoo 4 days ago
In over 30 years of using source control, I've never once worked on something where it's useful to include the component (article calls it scope) in the description in a standardised way. It's obvious what components are affected based on where in the source tree the affected files are. Similarly "bug", "fix" or "feature" adds no useful value. It's important or it wouldn't be checked in.
The only thing I've found useful, and which the article doesn't even consider, is a link / id for the relevant change request. The commit already contains all the information about what was done in the change, what's missing is the context about why.
Even on my solo projects I include a JIRA reference in square brackets before the description. If it's just something I randomly decided to fix during the course of development, I'll create a short 1 line JIRA to get an id and explain the why there.
Comment by eikenberry 4 days ago
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.
Comment by ralferoo 4 days ago
[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.
Comment by andrybak 4 days ago
> 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.Comment by ralferoo 3 days ago
[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.
Comment by andrybak 3 days ago
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.
Comment by dinfinity 3 days ago
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.
Comment by atq2119 3 days ago
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?
Comment by ralferoo 3 days ago
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.
Comment by saltcured 4 days ago
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.
Comment by ralferoo 4 days ago
That said, knowing the commit ID something is fixed in, so that the PM can track what build it emerges in is useful.
Comment by lelandfe 4 days ago
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)
Comment by rootnod3 4 days ago
Comment by bluGill 4 days ago
Comment by sokoloff 4 days ago
Comment by bluGill 4 days ago
Comment by ralferoo 3 days ago
The data in the ticket system should be considered important as it's the primary interface through which developers, QA and design share information.
Comment by bluGill 3 days ago
Comment by sokoloff 2 days ago
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).
Comment by bluGill 1 day ago
Comment by mmcnl 4 days ago
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.
Comment by xorcist 3 days ago
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.
Comment by jsve 4 days ago
Comment by eikenberry 4 days ago
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.
Comment by dualvariable 4 days ago
For GH issues you can always navigate back to the PR discussion (which should have linked issues and other pointers in it) from the commit.
Of course when we switched to GH issues, we largely abandoned JIRA and years later the instance got turned off and deleted. Now all those JIRA tags are entirely useless.
IMO that actually argues for tight coupling between your issue tracker and your git repo. And what you really want is portability (which I don't see how you get other than with tight coupling). Ideally there would be open standardized formats, but as it is, github is the 800# gorilla that defines the format and as long as gitlab and other clones can slurp in github project metadata (or at least PRs) then that effectively gets you closer.
But any way... Fixed, immutable pointers to an Atlassian product that you might not be using in 5 years is not a good policy. I'd sooner accept the policy that the git commits needed to stand entirely on their own and all the information about the "why" of the change needed to be baked into the git commit or the comments in the source (I think that fails, though, since everyone is overly terse in git commits and summarizes issues and loses information--and the back-and-forth dialog in a PR discussion is useful because it contains more than just one person's voice summarizing the reason for the change).
Comment by Izkata 4 days ago
We did Bugzilla -> FogBugz -> Jira. Almost all the data was lost every time, no one bothered with migration except for the maintenance project. Worse, even on Jira we lose cases as teams end and hand off the code, and the Jira project is closed so no one else can access it.
We've also done cvs -> svn -> git. All the commits have survived migration.
I do keep including cases in the commits messages, if nothing else it'll help link things together in the future, but never rely on them for context a future maintainer might need.
Comment by codethief 2 days ago
I agree that this is a problem but at the same time associating commits with a ticket number is useful, especially if I have dozens of commits on a single ticket and am doing trunk-based development (so not all commits are on the same short-lived branch). Maybe the lesson here is that, once completed, tickets should be exported and stored in the Git repository.
Comment by mystifyingpoi 4 days ago
Sorry to be nitpicky, but why did you abandon a tool that contained a lot of valuable knowledge? That's not the fault of GH nor JIRA, that's your fault. At least you'd back up descriptions + comments from these JIRA sources.
Comment by dualvariable 4 days ago
Comment by Macha 4 days ago
Comment by oskarpearson 4 days ago
Comment by ralferoo 4 days ago
Comment by ralferoo 4 days ago
Comment by bluGill 4 days ago
Comment by SamuelAdams 4 days ago
Comment by pseudalopex 4 days ago
Comment by llimllib 4 days ago
If you have somebody willing to write custom release messages, that's definitely better; but conventional commits is better than nothing for it.
Comment by ralferoo 4 days ago
If a developer is being asked to do that, it's a good sign that the PM isn't doing their job properly.
Comment by pseudalopex 4 days ago
Comment by mystifyingpoi 4 days ago
Comment by nkrisc 4 days ago
Comment by pseudalopex 4 days ago
Comment by splix 4 days ago
And the main case when that developer reads the commit message is when he doesn't understand _why_ that commit exists. Not what it changes, but what is the purpose of certain lines. So he runs "blame", sees commits, the original developers are not with the company anymore, the old JIRA may not exist too, and the only hint is the commit message.
Comment by literallyroy 4 days ago
Comment by oskarpearson 4 days ago
[edit] At the bottom of https://scopedcommits.com/ I mean
Comment by chickensong 4 days ago
If you're not using/tied to an issue tracker, embedding tags like these in git gives you some basic metrics.
Comment by Ferret7446 4 days ago
Actually, this is also similar to classic OOP, where people use a contrived method of structuring their code.
Comment by omcnoe 4 days ago
Comment by arcticfox 4 days ago
Scope might not be important to every project, but the feat/bug etc taxonomy might be the least useful focus of them all.
Comment by procaryote 3 days ago
Comment by adammarples 4 days ago
Comment by procaryote 3 days ago
What does the jira ticket give you that a longer PR message can't do better?
Comment by adammarples 1 day ago
Comment by calvinmorrison 4 days ago
JIRA tickets can help to, its about giving context to why the commit exists.
I find the 'component' label most helpful in large monorepos.
Comment by dotwaffle 4 days ago
[0] https://www.kernel.org/doc/html/v7.0/process/submitting-patc...
Comment by layer8 4 days ago
Comment by jonathanlydall 4 days ago
Cleaning my kitchen after a meal may be a chore, but it’s not an intrinsically bad or unpleasant experience most of the time, it’s just good hygiene and afterwards I have the satisfaction of things being clean. Not cleaning the kitchen feels way worse to me as it ultimately leads to other far more unpleasant situations.
Such it is with updating dependencies, it generally needs to be done, so it’s good to do it, but it’s in no way noteworthy, so chore describes it perfectly, to me it signals that: “it’s work that needed to be done, but not for a feature, functionality change or bug fix on this particular code base, so you’re unlikely to see much change”.
Comment by gawa 4 days ago
This is why I never use it and almost always pick 'feat' to please the linter. Because I can't help considering that any change worth committing is improving the quality of the code in one way or the other, and thus a feature.
Comment by jasonjmcghee 4 days ago
So now I associate it an automated pr vs authored
Comment by gdevillers 4 days ago
Same idea without the pejorative aspect.
Comment by williamdclt 4 days ago
Comment by jsve 4 days ago
Comment by embedding-shape 4 days ago
Comment by julik 4 days ago
Comment by mh-cx 4 days ago
To me this is almost the most important information in a commit message. I don't know how often in the last 15 years I was cross checking the issue description referenced by some old commit to get the full context of a change. I also felt that this habit is kind of standard - until i had to learn about "conventional commits".
I never got the hype.
Comment by jibcage 4 days ago
fix thing in foo
Issue: ABC-123
Git has plenty of builtins for parsing and formatting these trailers, so you can easily create custom git log aliases that let you see them inline and parse them for use with CI.Comment by epmatsw 4 days ago
Comment by codethief 2 days ago
git commit -m "PROJECT-XXXX Foo the bar to baz the qux"
in my shell history, which means 1) I can easily create follow-up commits under the same ticket number (no having to type the ticket number again), 2) I don't have to keep remembering the ticket number once I created the first commit on the given ticket. I'm sure I could set up an elaborate set of shell scripts and git aliases to auto-insert a ticket number as structured data at the bottom of each of my commits. But good luck convincing the rest of your team to do that.Also, having the ticket number in the subject line means every git-related tool I use will always display it (even if the rest of the message gets cut off).
Comment by jadar 4 days ago
Comment by andix 4 days ago
Most tools cross-link them as long as #<issue-id> is mentioned anywhere in the message. It's also useful the other way around, open an issue and see all associated commits.
Comment by willy1234x1 4 days ago
Comment by chrishill89 4 days ago
Personally (without conventional commits) I tend to put them at the end in parentheses if the commit has something to do with that issue. But if there is a stronger relationship like that it fixes the issue, I put a `Fixes` trailer in the message as well.
Comment by IshKebab 4 days ago
It's fine for it to be in the description.
Comment by hebleb 4 days ago
Comment by IshKebab 4 days ago
Comment by andrybak 4 days ago
When working in big teams, it can be very hard to increase the usefulness of commit messages. On the other hand, enforcing inclusion of a Jira issue key in commit messages is easy to implement. Relying on issue tracker descriptions can be a difficult proposition as well. Quality of individual ticket descriptions can be low; depending on how responsibility for maintenance is handled, the bug tracker migrations can sometimes be handled improperly and information can be more easily lost than in a Git log.
Comment by IshKebab 3 days ago
Comment by leni536 4 days ago
Comment by alanwreath 4 days ago
Comment by compiler-guy 4 days ago
Comment by willy1234x1 4 days ago
Comment by AlbinoDrought 4 days ago
Comment by beart 4 days ago
Comment by a-dub 4 days ago
conventional commits are pleasing, but questionable actual utility. the code speaks for itself. the actually useful information is a well chosen title and the context for the change.
Comment by c-hendricks 4 days ago
All ours at work do: "feat[component]: DEV-1234: description"
Comment by chrishill89 4 days ago
I can not say anything nice about conventional commits. The format takes up space in the most-read part of the message. The categories or types have little information. They can be replaced with an honest English verb embedded in the subject like a sentence. It also reads way better with just a sentence instead of three kinds of punctuation (:, (), !). Okay, I can tolerate an "area" in the subject. And that predates this conventio.
At my dayjob we make a webapp for non technical people. I can write a changelog for that just fine (in norwegian). The commit messages are irrelevant to the users. And demanding that all commits should be good enough for an end-user changelog? That's not happening for us anytime soon.
Use footers/trailers instead.
Comment by RVuRnvbM2e 4 days ago
I fully recognise that it doesn't make sense for huge projects like the Linux kernel to do this. But for 99% of projects conventional commits combined with semver vastly improves the release process status quo and makes it easy to automate.
Comment by WorldMaker 4 days ago
`git describe` is easy to automate for CD, but can leave version number decisions to people via `git tag` choices (and/or GitHub Releases) rather than trying to guess from commit history magic keywords.
Comment by herpdyderp 4 days ago
Comment by xigoi 4 days ago
Comment by RVuRnvbM2e 4 days ago
Comment by xigoi 3 days ago
Comment by IshKebab 4 days ago
Comment by Benjamin_Dobell 4 days ago
EDIT: I didn't see this covered in the article on my first pass. It is covered though. My apologies.
The type of the commit informs the automated workflows how to handle the commit. This is why it comes first.
For example, if you're performing CD, if you only commit a bunch of `fix: ` then only your semantic versioning patch version number is incremented. If you commit a `feat: ` then it's a minor version is bump. `feat! ` is a major version bump.
Even if you're not using CD for releases, semantic commit messages are sometimes used to automate change log generation. Granted, your change logs should not typically include the Git commit messages themselves — those are developer facing, not user facing.
Comment by mcluck 4 days ago
Comment by Benjamin_Dobell 4 days ago
Why on Earth are people not writing commit messages for their reverts? They should have semantic commit messages just the same as any other commit.
Unless the point is that they're not following per-commit CD, and if you commit then revert that commit before a release was made. That sounds like a process failure. Which of course, process isn't infallible, and neither is the automated version management. If you screw up, use an escape hatch — just like reverting a commit that had previously gone through code review and been merged.
Re: change log generation. The article says change logs shouldn't have commit messages. I agree. Many tools (e.g. Changesets https://github.com/changesets/changesets) use the semantic commit type to sort change log entries, but require you to write those user facing change log entries separately.
Comment by beart 4 days ago
Comment by layer8 4 days ago
Comment by beart 4 days ago
If you are releasing upon every push to main/master (following what semantic release and conventional commits provides you in terms of automation), then it makes sense to perform major version bumps for the reverts.
If you have a manual release strategy, then it might not make sense to use these tools in the way they have been designed.
Comment by layer8 4 days ago
And if you don’t have these kinds of dependents, then the versioning scheme isn’t important anyway.
Comment by claytonjy 4 days ago
I think that could be simplified, so the tool can tell that a commit is reverting a breaking change and thus the version should be decremented, but at least there's an escape hatch.
Comment by what 4 days ago
Comment by Benjamin_Dobell 4 days ago
When I encounter a bug in a dependency of mine. Before I worry about submitting a PR, the very first thing I do is grab my version number and check the commit logs for fixes since my version number.
If I'm trying to decide whether I should bother upgrading, I scan the log for new features.
It's the title, not the details. The commit message body should contain MUCH more detail than the title.
If you don't like it because it looks ugly. Sure, that's subjective. And actually, I agree. Because it's standardized though, Git interfaces could even be configured to trim this off and provide different visual styles for the different kinds of commits. The types could be used as search filters too etc.
Now, I get people don't like the look of them. Neither did I when I first saw them. Then I started using them and found them useful.
It's fine, people have different preferences, it's just a convention and it's not going to work for every project. The article itself just doesn't seem to hold any water.
Comment by compiler-guy 4 days ago
Comment by jacobsenscott 4 days ago
Comment by Benjamin_Dobell 4 days ago
If I'm at the point of contributing a PR to a dependency, I've already identified the root cause in detail. There's no way a change log should be going into that level of detail, or else you're just duplicating the Git log for no reason.
Will the change log make mention of fixing the bug? Perhaps. But I'm going to want to read the technical details of the fix to make sure they've specifically addressed my issue, and not just a similar problem. What is the performance impact of the fix? Are there security implications they've explained in the commit message.
I'm a software engineer, not an end user, I want the technical details of my dependencies.
Comment by xer0x 4 days ago
Lately I use CalVer instead of SemVer, so it hasn't been an issue. I like the idea of smart auto-bump for versions.
Comment by codybloem 4 days ago
Comment by voakbasda 4 days ago
Comment by chrystalkey 4 days ago
Ill add: I am personally put off in the same way your parent comment is, because hard stances are usually wrong, and I like a bit of nuance in my life.
Comment by zug_zug 4 days ago
Comment by pseudalopex 4 days ago
Mildly toxic was the same but worse in my opinion.
Comment by djeastm 4 days ago
Edit: Looks like they changed the title to be less provocative. Good for them
Comment by some_furry 4 days ago
There is a meme that inspires some of this genre of title, fwiw
Comment by lardissone 4 days ago
I don't like conventional commits much neither, but let the people use whatever they want!
Comment by matheusmoreira 4 days ago
Comment by brzz 4 days ago
A changelog is user-facing”
I'd say that ship has probably sailed. Most companies are happy with “Bug Fixes & Performance Improvements”. At least if they're not going to put the effort in, then a generated changelog is better than nothing.
Comment by karmakaze 4 days ago
Funny to ask to stop doing something I don't do or never even heard of. I typically only mark database schema migrations or other major things with special prefixes.
Comment by beart 4 days ago
Comment by pancsta 4 days ago
Comment by osigurdson 4 days ago
Comment by jeremyjh 4 days ago
Comment by c-hendricks 4 days ago
Comment by jeremyjh 4 days ago
Comment by c-hendricks 3 days ago
Comment by jeremyjh 2 days ago
Comment by zenoprax 4 days ago
> refactor(core): Update webmcp support to use document.modelContext
As the author points out, the line between a fix, an improvement, and general clean-up is blurry and dividing each semantic change into its own commit (and possibly squashed later anyway) is just creating work for no one's benefit.
I think Conventional Commits are just an artifact of trying to automate SemVer rather than solving any of the other problems directly. I don't think changelogs should be automated anyway - I can `git log` that if I want a list. A changelog is an opportunity to communicate to a wider audience what is actually going on under the hood.
Comment by cityofdelusion 4 days ago
If I only worked with seasoned devs, I wouldn’t use it, but that’s just the reality of my work. It also has a bonus of forcing AI agents to write in the same form as well instead of their random personal flavor. Precommit hooks stop everything before it gets in front of my eyes for review.
Comment by Merad 4 days ago
And does it actually accomplish that goal? I've been on several projects where someone pushed CC on the team with this reasoning. Every time my experience has been that you get the same crappy messages with a tag that may or may not be accurate.
BTW, AI absolutely knows how to bypass pre-commit hooks and will do so when they come up with some reasoning why their situation is an exception to the rule. I've watched them do it. The only way I've found to strictly enforce things on an agent (tests, linting, whatever) is to use a claude pre-command hook that will block git commit if the checks don't pass.
Comment by akersten 4 days ago
> fix: prevent foo from bar'ing
The whole idea of conventional commit is:
> fix: [problem]
so the correct conventional commit would be:
> fix: foo bar'ing
which is succinct and perfectly fine.
Comment by jacobsenscott 4 days ago
Comment by procaryote 3 days ago
Comment by 0x457 4 days ago
Comment by chrismorgan 4 days ago
> fix: prevent racing of requests
Though the example in the actual specification, “fix: array parsing issue when multiple spaces were contained in string”, is more inconclusive (and frankly doesn’t really make sense as a description).
Comment by darknavi 4 days ago
# Bug Fixes
- foo bar'ing
Comment by SebastianKra 4 days ago
Comment by jacobsenscott 4 days ago
You can do the same when you write commit messages. "Wrap user and account update in a transaction" - "Delete temp files after use".
Comment by flexagoon 4 days ago
Comment by SebastianKra 3 days ago
Comment by sandstrom 4 days ago
If one needs to put metadata in commits, usually better to just put it in a Git trailer.
https://git-scm.com/docs/git-interpret-trailers
`Co-authored-by: Alice` is a common one, but you can have anything in there.
Comment by olivierlacan 4 days ago
I've had to contend with Conventional Commits both in the OSS world and at work as it proliferated from what seemed to me like robotic adoption by folks who were even loosely associated with the Angular ecosystem (remember that?).
I've always had a stance with KAC that folks trying to automate changelog creation (prior to LLM rise, mind you) were focusing on the wrong thing. I still think there's a fundamental difference in focus between what you write in a git commit and what you present in a changelog.
I know there are fundamental philosophical differences for folks who were used to HISTORY vs. NEWS vs. CHANGELOG but with the growing adoption of KAC-like CHANGELOG.md files and Release Notes (often not synonymous) I think we're thankfully past the weird era were maintainers dumped raw git log ranges between two tags and called that a changelog. I'm sure some still do it. But that's what Conventional Commits tries to replicate.
What's really odd to me is that this assumes (broadly) that every single commit in a repository is relevant to the eventual version release changelog (or release notes). Even if you assume some CC types get filtered and deprioritized from generated changelogs by some tools, it's still a huge miss on what communicating about a release typically means: these change likely matter to you as a package dependent or direct user, while others were omitted for good reason.
I'm trying to articulate that much more clearly in KAC 2.0 because there's a fundamental paradigm shift when a robot can now analyze recent work (yours or theirs) and craft changelog entries that appropriately shift the audience perspective from "git message for me/us in the future to understand this change" to "changelog entry for you/them to know what this group of changes means".
[0]: https://keepachangelog.com
[1]: https://github.com/olivierlacan/keep-a-changelog/pull/600 if anyone's curious and wants to get involved
Comment by julik 4 days ago
The article is 100% on the mark.
Comment by jacobsenscott 4 days ago
Comment by chickensong 4 days ago
The CC standard may not be for everyone, but having some convention is often helpful. git log --pretty=oneline of structured format gives you broad filtering that's useful. Just writing like a human doesn't give you that ability and you're forced to read every line.
Comment by procaryote 3 days ago
Comment by chickensong 2 days ago
Another example is basic metrics stored right there in git. Did changing your testing strategy result in less follow up fixes after feature deployment? You can get that signal with a shell | pipe one-liner.
Honestly I'm not die-hard CC convention, but I think it's better than nothing, which is what the person I was responding to was suggesting. If you're using an issue tracker, having a convention to prefix or trailer the commit with the issue ID is the highest value IMHO. The point is having some convention to get teams on the same page and assist with git meta work.
Comment by wstone 4 days ago
Comment by estetlinus 4 days ago
Comment by lemonwaterlime 4 days ago
I spent some time recently coming to the conclusion that I did not prefer CC, but wanting some reliable structure. In the end, I found I was coming up with convoluted schemes that were getting in the way of actually solving my real problems and just settled on the tried and true:
“When applied this commit will...”
- Add <functionality>
- Update <existing>
- Refactor <while keeping same boundary behavior>
- Remove <some subsystem or functionality>
- Cleanup <documentation or style>
I don’t consider this to be a complete taxonomy, but it does let me get on with my day and covers most things, especially when combined with thoughtful commit messages.Comment by turadg 4 days ago
Another issue is that once the commit lands on trunk, you can’t revise the entry without editing history. You have to remember to fix it after the changelog is generated.
Changesets (https://github.com/changesets/changesets) is a much better approach. We adopted it in Endo (https://github.com/endojs/endo/tree/master/.changeset) and it’s been a clear improvement.
Comment by jmull 4 days ago
Keep a change log.
Comment by beart 4 days ago
Could/should the changelog be considered a first-class deliverable with care and attention provided? I think so, but I'm not in a position to exert direct control over that across dozens of repos and team members.
Comment by CharlesW 4 days ago
In my experience, LLMs are great at reviewing changelogs for potential gaps from a user POV (and even creating draft changelogs wholesale, if you're backfilling) based on git history.
Comment by jsve 4 days ago
Comment by m_m_carvalho 4 days ago
Conventional commits are most valuable to me as historical context rather than as a release-management tool.
The larger the project becomes, the more useful that context gets.
Comment by radlad 4 days ago
Comment by d0mine 4 days ago
Comment by cperciva 4 days ago
And the issue isn't whether you can remember what you changed yesterday; this is largely about making sure other developers can quickly identify relevant commits. If you're a solo non-OSS developer, this is entirely relevant to you.
Comment by xg15 4 days ago
Comment by WorldMaker 4 days ago
To some extent the "type" is simply about trying to limit/standardize the number of possible "verbs" to start a commit headline with, in which case Conventional Commits made the mistake of mixing verbs and nouns (fix and refactor are verbs but feature and chore are nouns) and adding distracting punctuation where English prefers none between the Verb and its direct object in a "Verb the thing" sentence. "Verb: the thing" only ever really looks awkward.
But also do we really want to limit the possible number of verbs that a headline sentence can start with when making commits? "Fix" and "Prevent" may often act like synonyms but there are connotative differences. In some cases "Prevent" may be a shorter way to explain why something needed to be fixed in a headline because "prevent" also says "stop a thing from happening that wasn't supposed to happen" whereas "fix" alone may not yield that extra context. The top line of a commit should be a short and sweet headline and sometimes the cleanest way to do that is to use the full gamut of English verbs at your disposal to tell the right story as quickly as possible.
Comment by NeutralCrane 4 days ago
Both fix and refactor are both verbs and nouns
Comment by WorldMaker 4 days ago
Comment by IshKebab 4 days ago
Comment by voakbasda 4 days ago
Comment by boltzmann64 4 days ago
Comment by esafak 4 days ago
My gripe about conventional commits is the redundancy: fix(ci): fix the foobar
Comment by heldrida 4 days ago
Without standards most developers I’ve seen are very careless.
I generally work with changesets to curate changes at the time of contribution in accordance to semantic versioning.
What’s great about CC is the simplicity.
Comment by epage 4 days ago
I don't do automated changelogs or versioning but it also makes it faster for me to do so.
I really dislike focusing on issue ids. I only want to jump to another tool if I need more information, so put it in the footer for after I've read what is there, like a front page news article giving you the option to go to the back to read more. Worst case that I've seen is people that think the Issue ID is all you need.
Comment by NeutralCrane 4 days ago
Is it theoretically possible that people can write good commit messages without a framework? Yes. Does that work out in practice across entire teams? No. Any kind of a convention for commit messages is an improvement.
Beyond that, type > scope vs scope > type or whatever is splitting hairs. The juice of that debate is not worth the squeeze.
Comment by nailer 4 days ago
> something like fix, feat, chore, docs, or refactor
'Docs' are also part of the program, they need fixes too, and features need docs. If the docs don't match the features because they're not being updated when the code is, the docs are a lie and waste other developers time.
Also if you were writing a standard: why would you randomly abbreviate 'feature' but not 'refactor'? That sounds like a nitpick but standards require great thought, this is a bit of a smell that there hasn't been much thought into designing 'conventional commits'.
Finally: the name 'Conventional commits' is a land grab (reminds me of when someone made a JS Standard and called it 'StandardJS', ignoring every existing popular standard). From the article, the *actual* convention is 'scope: work"
- Linux
subsystem: description
- FreeBSD prefix: description
- Git area: description
- Go package: description
- nixpkgs pkg-name: descriptionComment by chrismorgan 4 days ago
And it’s ugly.
(But I suppose I am talking primarily about the first line part. The “BREAKING CHANGE” bit is potentially actually useful, though being incompatible with git-interpret-trailers despite leaning on git-interpret-trailers for other footers seems a bit crazy.)
Comment by codingjoe 4 days ago
However, actually writing a good commit message is an art form few have mastered.
I wrote a small natural language linter to teach my teams meaningful technical writing: https://github.com/codingjoe/word-weasel
Comment by matttproud 4 days ago
(I can't believe nobody has pointed this out yet.)
Comment by tomjakubowski 4 days ago
https://tbaggery.com/2008/04/19/a-note-about-git-commit-mess...
Comment by flakiness 4 days ago
Comment by jsve 4 days ago
Comment by tcmart14 4 days ago
We also tend to do something like
bug-ios: <case name>
feat-android: <case name>
So we don't have generic stuff like
bug-ios: fix memory issue
Comment by rlpb 3 days ago
Comment by mckn1ght 4 days ago
I’m just unsure that the short title is the ideal place to put this kind of tagging info: the kind of fix, and optionally, the relevant component(s). I find sometimes that can take up the majority of the title.
A forge could consume the git-notes and decorate a commit/pr accordingly. Heck, GitHub PRs already have a labeling system in place, just have to add some glue.
Comment by docheinestages 4 days ago
Comment by cadamsdotcom 4 days ago
After that it’s great to know where is primarily intended to be impacted.
Then look for what the change is and does.
There are some good ideas in this proposal but the author is creating a false dichotomy by saying the current standard should be scrapped. Two things can coexist and both be good. I hope the author reconsiders their approach in their future promotion of their idea.
Comment by weinzierl 4 days ago
That being said, when I finally committed to using them something in me broke. Most of my career work was double faced. One face to the customer where you need to keep Tatemae under all circumstances (UI, Tickets, etc.). The other was the code and commit messages where you still kept your professionalism but you could be open and speak the language of your peers.
This time is over, maybe for good, but a tiny part of me misses it.
Comment by scelerat 4 days ago
git log --pretty=format:"%n%h %s" --name-onlyComment by skydhash 4 days ago
Comment by shmerl 4 days ago
This makes neovim plugin manager highlight the change differently which brings attention to it when you update stuff.
So please do use it instead of complaining!
I do like the suggestion of
scope!: ...
if it will be treated the same way with breaking changes reactions.
Comment by bfeynman 4 days ago
Comment by agentultra 4 days ago
Comment by dang 4 days ago
ReleaseJet – Release notes from issue labels, no Conventional Commits - https://news.ycombinator.com/item?id=47847605 - April 2026 (1 comment)
Why Use Conventional Commits? - https://news.ycombinator.com/item?id=46940152 - Feb 2026 (1 comment)
Conventional Commits Considered Harmful - https://news.ycombinator.com/item?id=46019218 - Nov 2025 (1 comment)
Conventional Commits Considered Harmful - https://news.ycombinator.com/item?id=45420887 - Sept 2025 (1 comment)
Conventional Commits makes me sad - https://news.ycombinator.com/item?id=44482546 - July 2025 (2 comments)
A specification for adding human/machine readable meaning to commit messages - https://news.ycombinator.com/item?id=40740669 - June 2024 (2 comments)
A specification for adding human and machine readable meaning to commit messages - https://news.ycombinator.com/item?id=34660646 - Feb 2023 (48 comments)
Ask HN: Are you still using conventional commits? If not why not? - https://news.ycombinator.com/item?id=33525754 - Nov 2022 (4 comments)
Conventional Commits - https://news.ycombinator.com/item?id=30950377 - April 2022 (1 comment)
I Hate Conventional Commits - https://news.ycombinator.com/item?id=29924976 - Jan 2022 (1 comment)
Conventional Commits - https://news.ycombinator.com/item?id=24208815 - Aug 2020 (23 comments)
Conventional Commits: A specification for structured commit messages - https://news.ycombinator.com/item?id=21125669 - Oct 2019 (95 comments)
Comment by mianos 4 days ago
Comment by hambes 4 days ago
the part about broken promises regarding breaking changes is _kind of_ fair, but only assuming tooling isn't able to track reverts. accidental breakages occure with every approach and better to have an approximation than no information at all.
Comment by djdeutschebahn 4 days ago
Comment by rawkode 4 days ago
The commit description and the pull request are for humans.
Comment by sennalen 4 days ago
Comment by awill88 4 days ago
Conventional commits doesn’t make a promise, it’s a specification. Words have power and meaning, this viewpoint is about more than a spec, it’s about the popularity and relevance that they clearly despise.
Conventional commits are like BEM syntax for CSS, it works if you pay attention. It’s structure around what developers do, which thoughtful limits. What is the problem with that? Is it the only way? No. But to say it’s encouraging the “wrong things” pshhhh
This author’s take is dog water for coders who yearn to be controversial and (clearly) focus on the wrong things.
Comment by spit2wind 4 days ago
Comment by ryukoposting 3 days ago
> Automatically determining a semantic version bump (based on the types of commits landed): This sounds nice, but the realities of software engineering often interfere significantly with the viability of accurately accomplishing this... imagine a situation where the breaking change you introduced was actually so breaking that you have to revert it... maybe the breakage is subtle and you don’t realise a change is a breaking change when you make the change. Only in retrospect realise that it’s breaking. You will incorrectly increment a minor/patch version when a major version bump is necessary...say you later add a commit which, in composition with a previously breaking commit, results in a diff which is not breaking. Similar to the revert situation, tooling would incorrectly identify a breaking change.
This is a problem with Semver, not conventional commits. You're liable to do this regardless of how your commits are formatted, which is one of several reasons why conventional commits are silly. But in this case, Semver itself drew semantic lines that aren't clear, and are easily broken.
Comment by skerit 4 days ago
Comment by cristaloleg 4 days ago
Comment by christophilus 4 days ago
Comment by caraphon 4 days ago
Also, we let AI write the code, are we STILL writing commit messages by hand??
Comment by rerdavies 4 days ago
Comment by rerdavies 3 days ago
Comment by thom 4 days ago
Comment by nintenddos 4 days ago
Comment by lezojeda 4 days ago
Comment by smrtinsert 4 days ago
Comment by 839720759 3 days ago
Comment by gitscope_ai 4 days ago
Comment by animanoir 4 days ago
Comment by murphomatic 4 days ago
Comment by ex-aws-dude 4 days ago
In other words a perfect topic for HN
Comment by bowlofhummus 4 days ago