A specification for adding human and machine readable meaning to commit messages
conventionalcommits.org
conventionalcommits.org
It is almost like signing all your commits with your name or the current date. (Yes, I had a coworker who did this.)
Better commit messages tell you what the situation was around the commit: Ticket number, or who wanted the change, or any other context that might tell you why the code was changed the way it was.
Consider the dev accessing your commit through "blame". What does that user need to hear? Not which file or subsystem was changed. But the reason there is a change in the first place.
My habit has been to prepare longer commit messages, a paragraph or two of explanatory text for that future developer, who is most likely future me.
Policy at my company now squashes all my carefully-prepared commit messages into the one-liner "Merged $BRANCHNAME into main". I will probably just switch to the three character commit message "WIP" like my coworkers have done.
many repos are successfully using conventional commits in a way that's not low value, clear and concise in message, and useful in blame and walking history.
I don't understand what is so appealing about a linear commit history. It's a fabrication of reality, and I have never been grateful for it, only enraged.
Why wouldn't you want to know what _actually_ happened? What is being gained besides an aesthetically pleasing "commits" tab on GitHub?
And those below-average developers probably aren't looking at the history at all anyway.
At any time, a developer might make another branch, then merge branches or squash the whole history of their branch or create a new branch and add the changes as if it was a fresh branch. Meaningful history is lost in those cases as well. Adding micro-managing process might get (more or less) predictable results, but it almost always pushes developers toward anti-patterns ensuring those predictable results are not what was intended.
Squashing large number of commits is questionable practice, though.
There's also "git log --merges" but that would presumably show any merge commits that happen to be present in a branch that is being merged so it wouldn't necessarily be linear.
If you disallow merge commits on GitHub, does that prevent a merge commit from being introduced as part of a rebase merge? If it doesn't, then presumably the only way to guarantee a linear history on GitHub is to allow only squash merging.
So, if you don't trust your developers to always do the right thing perhaps you should either only allow merge commits or only allow squash merging?
1. you can have a linear history by rebasing then fast-forwarding onto the target
2. but it’s complete nonsense, learn your tools e.g. `git log --first-parent` (and how to merge), merge commits work perfectly fine
3. and importantly you can rebase then merge, which cleanly packages a set of changes behind a single merge commit without interspersing with other branches, and yet without losing the branche’s details
That sentiment is not IMHO a particularly potent argument for _anything_ related to engineering.
Accuracy, not convenience, should be the goal. If you need to make consuming the data more convenient, that should be the focus.
To be clear using the word "correctly' is putting a lot more confidence behind my opinion than I ever intended, i.e. I am open to counterpoints, and do not portend to think a one size fits all policy is realistic.
There is never reason to squash. The best of both worlds is to always force a merge commit (disable fast-forward merges) and look at the log formatted whichever way you want (--first-parent shows people that linear history without destroying history).
Doesn't that belong in the code itself? Do we really want the intention of a change to sit under multiple levels of blame?
A commit can certainly have computer readable metadata I presume!
Of course it can.
> which is primarily about succinct human understanding and setting context.
You do know there is essentially no limit to how long a commit message is right?
Yes? How would you encode the reasons for a change and for the way the change was implemented in code, dozens of lines of comments and ending up with files which are 90% comments floating in the void long detached from any code they were relevant to (and which may not even exist anymore)?
After first line you can write all the additional information.
WTH? That’s the dumbest policy I’ve ever heard of. Who made this up?
On the other hand, a branch name can be 255 characters, time to get the entire thing in there.
- GitHub uses the pull requests title and description as the merge commit description, as well as linking to the pull request. This means all of our mainline commits now have links to relevant Jira tickets, context, change requests, and feedback on the PR. - The mainline commits are new linear and easy to read through, to the point where I was able to make an internal tool that can show everyone where every commit is at, with a nice description, and what stage in the production release cycle it’s at. - git bisect is a lot easier now. No one has to bissect through all kinds of “wip” or “fixed test for x platform in ci” commits. - most devs never have a need to rebase. Ever. This means devs can stack PRs against each other and test each others code together without having to deal with a rebase causing a bunch of pain. - All commits in our main branch now pass CI. - all commits in our main branch are now GPG signed by the org, without devs needing to configure commit signing locally.
So I prefer the flow of rebasing before merge. This way main stays linear and readable and you have the descriptive level at the commit level. The Context for the full merge can be found in the ticket corresponding to the change.
Sounds like the perfect use of an inline comment rather than change history?
On the other hand the worst offenders are refactorings with the commit message "refactoring". Then you can go hunting. Then a comment would have helped.
In a perfect world we would have both, good inline comment, well written commit message and a ticket with more than a title.
I think they are more medium quality commit messages, low value would be significantly less informative than that.
Aside from that while I agree you should have ticket number etc. integration between ticketing system (generally Jira, let's be honest) and your git provider is probably non-existent so it is of less real value in finding what you what to find when looking through that git providers interface.
In fact if your commit message does not say what was done you will have to go into the commit to read the code and figure it out, which obviously is wasteful if you are trying to find the most likely commit in a dozen that caused a problem.
This doesn't mean a "why" shouldn't also be required.
Finally, I really dislike the specifics of conventional commits. "feat", "fix", and "docs" are not particularly interesting distinctions. Just put whatever you were going to put in parens and save yourself 6 bytes.
// if ID exists in commits
if (commits.has(id)) {
Big sigh every time I see this, especially if the code is "well-commented" // if ID exists in commits
if (commits.has(id)) {
// make no changes
return
}
// add ID to commits
commits.add(id)
// log ID to console
console.log(id)
On the other hand, LOCs through the roof, 10x developer right here.Regarding choice of types: why „feature“ is shortened to „feat“? If there’s a type for feature, why another type is „fix“, not a „bug“? Semantically naming should be consistent.
Automatic relationship with semver is questionable. Fix can be a change in architecture that deserves major version. Implementation of non-functional requirements is not a fix, yet it does not introduce new features and thus not a minor version increment. These are just two examples where inferred version is not what it could be. Making possible explicit expression of intent would help, e.g. by adding some tag like [minor]. Example:
„APP-143:fix:major - migrated from mongodb to postgres“
„123456:new:patch — added logging of requests“I've had some coworkers argue that the first line of the commit ("subject line" in git) is very important real estate, not to be wasted on a ticket reference, where it could instead hold a human readable summary. There's some merit to that. But they'd still include a reference to the ticket inside the body of the commit.
Depending on how excitable one's org is about creating and migrating between issue trackers, sometimes a ticket reference can still be very ambiguous. I've seen one enterprise project migrate between different JIRA instances within the space of a couple of years, where depending on which instance you plugged the same ticket reference into, you'd get a completely different ticket!
Bumping the minor version for this is fine in semver. It's a MAY in the spec.
Conventional Commits - https://news.ycombinator.com/item?id=30950377 - April 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)
Full title: Conventional Commits A specification for adding human and machine readable meaning to commit messages
The thing that it really helps doing (when you're using it) is avoiding doing multiple things in one commit. Features and refactors and fixes belong in different commits.
With this I can also look at my git log and quickly see on the places where I changed things (rather than style or refactor or docs or tests). This commit, with a few lines did this - not "this change was part of this much bigger commit."
Haven't tried it but I will.
I often have trouble with enough room to have a meaningful subject but the time I include commit scope and Jira ticket number, but I don’t mind, I normally use the body anyway.
all of my personal repos use it and any professional repos I have a say in use it.
The reason why commit messages are free form is so they can remain free form.
It’s hard enough to make a model of the world in code. Why in hell would you want to impose this on commit messages?
[1]: http://karolis.koncevicius.lt/posts/improving_github_issue_l...
Please do not skip writing a meaningful commit message (explaining the why) because an issue number is referenced.
At a previous job all commits referenced issue numbers of a dead issue tracker no one had access to anymore, rendering git blame useless.
Recently I'be started using "subsystem: change" type. Knowing the area seems like the most important starting queue.