I do it almost daily too. What _is_ rare, is finding a commit message that tells me anything useful that I couldn't have derived from the diff also. I don't need your life story, but sometimes some context about why something was needed is great.
Exactly. Im in git history all the time. But the messages themselves…eh. Im basically always looking for a change in a specific file or set of files, and then I just pull up the diffs.
Author here. Yes, the diff should tell you more, but you shouldn't need to look at the diff until you have an idea what the contents of that diff are about. It's like the links on the hacker news home page -- clicking them will always tell you more, but the index should be geared for the use case, which is scanning, typically.
I'm not sure that suits everyone's most common use case. (I'm not arguing that it may well suit yours.) I guess on paper it makes sense that commit messages are the top-level entry point to changes. But since we're packaging up a lot of our work in merge requests, the commit messages already get snowed under. Folks arrive in a merge request, and often can't care less about the commit messages that make up the merge request, they may read the message on the merge request, familiarize themselves (ideally) with the story in (ugh) Jira, and then jump to the diff for the review they came there to do. It's the later version of you that is browsing through the code base and wants to understand how a certain current piece of code came about, who then clicks on the gutter in, let's say, IntelliJ, and clicks through to the commit, where both the diff and the commit message are shown.
Indeed, and since we don’t do pull requests (we pair, mob, and/or do live code reviews), the after-the-fact git blame or the git log to see what has changed recently is what tends to matter.
I agree that when I did PRs I didn’t tend to care about the commit messages when I was reviewing them, but even when I did do PRs I cared about them later any time I was trying to understand how, why, or who forensically.
It is so odd to me as I don't remember a single instance during my 10 years of experience having done that. Only if I was asked by someone else in the org why something is the way it is have I gone to history to see what the ticket number is for the referred change to get an explanation and this is more related to the product.
I wonder what is so different about our workflows, that some people do it all the time and others almost never.
Are we working on somehow very different things.
To me I find that code is the source of truth and current state, it doesn't really matter to me as much why or how something came to be as I look more into how I can make the current thing work with what I am to do.
I do, and I also work on legacy systems. It just never occurs to me that commit history would somehow help me instead of just looking at the current state of the code.
I would say however that the commit messages mostly are just squashed pull requests with ticket names and single sentence so I'd agree that they wouldn't be very good for that purpose, but I don't see anyone at the org complaining about this.
It's mostly on the Internet I read how others use the git history, but I haven't seen anyone really doing a lot of that in real life.
For me it's usually blame, look for a line that hasn't been touched by some triviality, then from that commit message either to a ticket reference, or, if absent or unavailable, to history shortly before and after. So yes, I do look at old history. In a codebase that has seen a lot of squash rewriting that won't be of much help of course.
> I would say however that the commit messages mostly are just squashed pull requests with ticket names and single sentence so I'd agree that they wouldn't be very good for that purpose, but I don't see anyone at the org complaining about this.
It does sort of feel a bit cargo culty sometimes. I expect commit messages are situationally important, as a function of the size and maturity of the project, the size of the development team (esp. the amount of developer churn).
That said, there's probably some fringe benefit to describing what you do in some fashion. It's a great way of making sure you understand what's happening yourself.
How does that work? Like a cargo cult behavior is a ritual you do because you think it will bring about some good through unknown means. Disregarding commit messages is the absence of a ritual.
The difference is that if disregarding commit messages has no effect, then it's still beneficial to do since you're saving effort vs writing elaborate commit messages.
Maybe version control is a cargo cult, then? You might as well just make commits without commit messages if the revision comment is useless. Maybe just squash all commits between versions so you just have one commit per version.
This is a demonstrably faulty conclusion. Even without commit messages, version control lets you do things that you would not be able to do otherwise, such as to roll back a failed refactoring attempt, for example.
It's still a substantial improvement to have known snapshots of the state of the code. It doesn't have to be in VCS, like you can roll it old school and save full zips of the code base, but snapshots are a tangible benefit that VCS offers that does not hinge in the slightest upon well written commit messages.
I look at past commits probably every week or two to track down why something is the way it currently is.
Having said that, I care very little about style and grammar of commit messages. Ideally I want them to say why the change was made, what the intended effect was, and where I can look for related work (bugs that tracked the work and have related commits or investigation attached to them, docs, whatever)
Hit rate on the information I'd like is not great, but if I get at least one of the three things then it's something I can work with.
I'd say I look at commits ~weekly, especially when trying to understand 'WTF did he do that?' - context of tracing the commits (and offtimes back to individual PR when commit is poorly formatted) is valuable.
I personally look more often at past commits, but I've still never really had a need to scan a list of changes like this. I really don't see the point of the advantage they're claiming, even if it's real.
What I normally do is, while investigating a tricky bug and finding some lines that don't make sense, look through history to see why those lines were introduced (to see if they fix something else), and perhaps when (to see which versions may be affected by a hard-to-reproduce bug). But that typically pinpoint a commit already, and I just need the commit message to explain why it was there.
What's tremendously useful for us to have in the commit message, is the ticket ID the work is related to in our issue management system, to the point where it is practically mandatory.
I see it as a matter of scoping communications. The issue management system includes a broader set of people than the git repo. You want the commit linked to the issue so that you can see the entire history behind the commit, including the business decisions, the designer making a call, the back and forth with QA etc. That can all be useful a year or two down the road if you want to understand why something was done a certain way.
Now there is some info about the change that perhaps only the devs would ever care about, and probably that can sit in the commit messages. That sort of happens naturally but there's not really a lot of it for us. But that seems to me to be the relevant thing from an organizational perspective, no one writes commit messages except for devs, and almost nobody except the devs reads them.
This is what I came here to say. Assuming the team is working from JIRA or something, put the ticket number in the commit message. The ticket itself is where your “why” goes.
It's really nice to have the actual reasoning in the commit history though. But maybe I was just scarred by the project that switched project management software like 5 times over its lifetime (but kept all of the commits) though.
I’ve been through this in a job. The commit messages were borderline worthless, ostensibly the context was in a JIRA ticket that hadn’t existed in a decade, and I couldn’t figure out if a change was a mistake or something clever and poorly documented. It’s frustrating, a huge waste of time, and runs the risk of introducing subtle defects into the code today.
I can't stand the ticket number in the message. It's an immediate waste of 6-10 characters on meaningless metadata that GitHub can pull from the body and link for you. Further, the numbers are sequential, so frequently VERY similar, and highly prone to typos, which is harmful to anyone even minorly dyslexic.
`git commit -m "Fix actual words that humans read" -m "Fixes: #234353"`
You could probably script this based on branch if you're one of those people who names branches after ticket numbers.
But my actual advice is that I think -m is a bad pattern that leads to bad commit messages, and omitting the message argument opens your EDITOR, and you should use that.
I wonder if Atlassian encourages and sells this as an ideal use case [for JIRA]. What a great way to make it really painful to leave their system if in order to make sense of your repo history you to need to maintain the references to their system. They are making your repo dependent on their ticket system...
Blame & diffs are much more useful to me in the context of GitHub. I don't care about someone's subjective ~50 char description of a change. The important part is the pull request itself and that it references whatever issue prompted the change.
Commit messages have only ever been useful in tracking my own intermediate work products. Often times, I will leave helpful bread crumbs in my commit notes if I know I won't be working on something for a few days. We strictly do squash+merge, so I don't have to worry about these things causing trouble for others. All of our commits into master have some standardized "Issue #1234" note as automatically copied from the PR title (which we do have ~standardized).
If we didnt have some git wrapper like GitHub available, then I suspect we'd be significantly more aggressive with policy around our commit messages.
<10 instances of looking at the commit history in >10 years is exceptionally little. I think you may have a different use-case if your commits are write-only and crafting commit message texts is probably a waste of time at that rate
Which is a very interesting take, for what it's worth. Might be worth a blog post what circumstances lead to this working well for your organization!
In my experience consistency is more important than any specific style of commit messages. Similar to style guides for code; there's plenty of ways to approach it, but the real value is the consistency in how things are written across all developers.
Like everything in software development, this is just personal preference without any actual evidence, a substitute for actually making software with quantitative quality metrics that users actually care about. Let's fiddle with our commit messages, PR formats, code formatting, etc. etc. etc. instead of addressing the fact that our website has 6 different fonts and makes 30 HTTP requests to show a few hundred bytes of text.
I totally agree, I have seen people get so fixated on this in addition to:
- review feedback format
- variable naming
- keeping line lengths to 80 lines
- log message formats (sweet jesus the amount of time wasted debating that alone)
Whenever I see these conventions about commit formatting they generally seem to focus on the first line (notable exceptions being Git and the Linux kernel among others I assume), one line is rarely enough to describe the change – I’m not advocating for writing an essay for a 5 line change though in some cases it might be warranted.
Professionally I rarely see useful commit messages, by useful I mean something that could be read by someone without context and get a general understanding of why a change was made. Frequently I have seen “updates” / “wip” etc. in the master branch.
More frequently I see that the quality of commit message decreases with an engineer’s seniority – though like every thing there are exceptions.
Author here. You're well within your rights to believe it is personal preference, but it's somewhat hard to refute the fact that it's easier to scan lists when you put the most significant (i.e., the part that varies the most) first. Imagine if every item on Amazon's list of products was of the format: "Product for purchase, Headphone, Sennheiser Momentum 4"
there are pros and cons to both verb-first and subject-first commit styles.
verb-first commits can be organised in a few categories.
since they are few commit verbs (fix, add, refact..), always use the same verb prefix for bug, features messages and you will have nice categories to scan/filter:
- add feature
- fix bug
- refactor logic
On the other hand, subject-first indeed put the important part first and let you search for a term:
- Instance configure template method called from constructor
- Store's project method is an alias for fetch
- Title is changed
Depending on the use case, are you often searching for something? or would you like to highligh the nb of bugs/features in the last release?, one style is better suited than the other.
For important changes, I like the linux kernel style:
oneline summary, details (problem, impact, solution..)
I prefer the first version, I didn't find the second version to be more "scannable" and it seems to me to be more esoteric requiring study to realize what was recorded. The first version is clear, each commit makes sense and is what I'd be grepping for when trying to find a commit.
"Change List", Perforce's name for the rough equivalent of a commit.
It's called a change list even though it's a single commit because Perforce tracks changes per file, so if you modify multiple files in a single commit, you are introducing a list of changes in their model.
Author here. The psychology portion isn't subjective -- things are easier to scan if the more important part is first. One would have a hard time refuting that. Also, there is some familiarity bias that comes into play when reading a commit message style that is foreign, so the experiment I offer may not be super compelling. We are used to what we are used to, and that takes some time to overcome. I know it took me a while to overcome it both in writing, scanning, and reading them. It was worth it for me and our team.
> things are easier to scan if the more important part is first
You skipped the step where "most important" is defined.
> "Specifier can be configured when constructing a store"
This is just about the worst type of commit message, in my opinion, only marginally better than an empty commit message.
Ok. Specifier can be configured when constructing a store. Is it supposed to? Is it the state before or after the commit? Is this just context, and maybe this commit changes documentation to reflect that reality?
You even say that reading a bunch of them is uncomfortable.
> It's not about the self. It's about the code.
Actually, it's about the change. When something broke, what changed. When a new release comes out, what changed.
Some people prefer the past form "Added feature X" instead of "Add feature X". On that I just say "be consistent".
Also note that your first batch of examples are inconsistent. "Whitespaces", "We don't use `::` to denote class methods", "Avoid __method__", past/present verb form, etc. The difference isn't just the form, but whether commits actually follow any style at all.
> I eventually recognized the benefit of scannability
Scannability is hugely important. People who disagree with your style of commit message don't disagree with you on that.
> For example, "Widget tests" is preferred over "Widget tests are added".
What about the widget tests?
> When describing a version increase, be explicit about both the old and the new version. E.g., "Package version is increased from 1.1.1 to 1.2.0"
Are version numbers ever decreased?
(1.1.2 can be released after 1.2.0, yes, but that's not a decrease even if something was backported)
We didn't need it. It was based on a-priori knowledge. For example, we don't write email subjects like: "Convey information about new release", or "Ask question about time off". We know from how the human brain processes content (eye tracking studies) that they scan in an F-shaped pattern. This puts emphasis on the content on the left. If the left side has no differentiation, this is, de facto, harder to scan.
You don't have to agree with me. As my colleague said, there are other, even more subtle things we are trying to convey and reinforce: https://news.ycombinator.com/item?id=38836919
> You skipped the step where "most important" is defined.
No, we literally do this every time we write a commit message. This is a usability issue. What is the most important thing to the reader?
> Ok. Specifier can be configured when constructing a store. Is it supposed to? Is it the state before or after the commit? Is this just context, and maybe this commit changes documentation to reflect that reality?
And yet, when all of your commit messages are in a consistent voice and mood, there is no ambiguity. Also, all of your questions are answerable from a self-evident perspective -- if you can rely on your teammates to care about your ability to understand what they write. Of course it's supposed to, otherwise why would I commit it? Of course it's the state after the commit, why would I talk about what was (How many newspaper articles about a celebrity's death have a headline saying they are sick?)? Of course it's not about documentation, it would say it was if it was. In short, you can make up as many holes as you want to poke through.
> You even say that reading a bunch of them is uncomfortable.
I said at first. See: familiarity bias
> What about the widget tests?
This is convention that one could argue requires memorization. I don't actually think it does, however, because of how we as humans interpret subjects/headlines.
> Are version numbers ever decreased?
They have been, and I hope it's self-evident how that commit message would be constructed on our project.
In any case, I'm not here to quibble about commit message formats. I documented ours and gave supporting rationale which is based on UX knowledge (and research, at the very least, see eye tracking studies). If you think that "Fix", "Fix", "Add", "Change", are the most important part of the commit message, then I'm not really going to be able to or even bother trying to convince you otherwise.
>> What's your evidence or supporting research?
> We didn't need it. It was based on a-priori knowledge.
Well, you may hold these truths to be self-evident, but that's hardly an argument. And since you say "It's likely what your team uses, as it is the commit message style that is typically recommended as a "best practice" you acknowledge that you hold a minority opinion.
"What I'm saying is self-evidently true" is unlikely to sway anyone.
And I find it dishonest to phrase that as "The psychology portion isn't subjective".
From your colleague:
> The reason that the "subject-first" approach is used is to get contributors to talk specifically to the impacts made to the software itself, rather than talk about themselves and their labors.
I don't recognize that description at all about the majority opinion. Yes, some people write terrible commit messages, but that's not the best practice you seek to upend.
> Of course it's the state after the commit, why would I talk about what was
You'd be surprised. It's more common in bug reports, but I've seen this in commit messages too.
>> Are version numbers ever decreased?
> They have been,
Oh, really? Do you have an example?
> In any case, I'm not here to quibble about commit message formats.
Thanks for clarifying that you base this policy on nothing but your subjective opinion, that there is no research to support it, and that everyone else is doing it wrong, because your subjective is clearly objective.
Nothing wrong with that. I do have a problem with you misrepresenting this as objectively better, with a handwavy "scan in F shape". Don't say it's based on research when it's just your "common sense". That's unprofessional.
> you acknowledge that you hold a minority opinion
An opinion being minority has no reflection on whether or not it is correct. See hand washing in the medical profession before it was understood, or batch sizes in the automobile industry before Toyota ate the west's lunch.
> And I find it dishonest to phrase that as "The psychology portion isn't subjective".
You can find it dishonest if you wish, but I'm trying to point to a body of knowledge I can't adequately convey in an article or a hackernews comment. I'm not trying to pull one over on you, I promise. As I said in another response, this is a design decision. Most design decisions are based on first principles, a-priori knowledge, expertise, a wide range of studies and observations over time, etc. If a person can't write down (convincingly) all of the tacit knowledge required to make the same decision, they are not being dishonest.
I'll say it this way: We made this decision based on objective factors. I do not expect everyone to be able to see our decision or our reasons in the same objective light and I'm not going to try to convince someone that doesn't. But telling me it's purely subjective is gaslighting, and impugning my integrity over it is just rude.
> You'd be surprised.
No, I wouldn't. I would be surprised to see it on our team, or any other well-disciplined team. This article is a tiny (and frankly pedestrian) part of our overall development process. I'm sure you'd disagree with just about everything else that we do as well, and that's OK as well.
> Oh, really? Do you have an example?
Sure:
mail package version is decreased from 2.8.0 to 2.7.1
This happened when we were forced to pin to an older version of the mail gem because of a regression in 2.8.0.
Note that the scenario you described: "(1.1.2 can be released after 1.2.0, yes, but that's not a decrease even if something was backported)" isn't relevant to our practice. We don't maintain multiple major/minor versions at one time of any of our packages. If we did, they would be on separate branches as the version number can only exist in one place (the gemspec) and the same exact rules would apply. That is, it wouldn't be a version decrease, it would be an increase from 1.1.1 to 1.1.2 on the 1.1 branch.
> An opinion being minority has no reflection on whether or not it is correct.
I entirely agree. But if you find yourself in the minority, then I encourage you to objectively consider what's more likely: Are you right, or are most other people right? Or maybe there is no right and wrong (aside from being consistent)?
Sometimes the minority is right. But usually that's not the case.
> See hand washing in the medical profession before it was understood.
Ooookayy. I would not compare any technical decision in this space to that. A bit grandiose. More traditionally one says "10k flies can't be wrong: poop must taste great!".
> If a person can't write down (convincingly) all of the tacit knowledge required to make the same decision, they are not being dishonest.
I agree. As long as they don't claim otherwise. I'm sure you're an expert, with lots of experience. Experience that creates a good judgement, and good intuition. But that also describes the majority of the experts, who, turns out, disagree with you.
>> You'd be surprised.
> No, I wouldn't.
Then... you disagree with the "of course", you said.
> mail package version is decreased from 2.8.0 to 2.7.1
What does that mean? A dependency version decrease? If this is a commit on the mail package itself, then what does it mean?
I'm going to assume that's a dependency version change.
"10k flies can't be wrong" is one thing, but "the majority expert opinion in my field is wrong"... is almost always wrong.
Most theories are wrong, even by experts. It's not even embarrassing to be wrong.
> Ooookayy. I would not compare any technical decision in this space to that. A bit grandiose.
One has to be able to understand an analogy for the point the person is trying to make -- it's not an equivalence. Obviously most software issues don't rise to the level of life or death.
That said, let's try a few others:
- Waterfall
- DCOM
- CORBA
- Web Services
- Microservices (as implemented by web developers -- per-entity web api to web api to web api cascading failure)
- Monorepos (not globally, with sufficient support these can work)
- Devs shouldn't write tests
- Fat Model, Skinny Controller
- Write tests. Not too many. Mostly integration.
- Single Page Apps for all
- SCRUM
- Story points
Most, if not all of those were embraced by "most experts", but are now demonstrated problematic or at least are knowably wrong from fundamental design principles. Note that statistically speaking, "most experts" are, at best, early majority. There aren't very many in the Innovators and Early Adopters, and crossing that chasm is rare, and hard.
We have a history in our community of intransigence, repeating mistakes, and expert beginners being the most outspoken portion of our community. They are the ones that have the most to gain by blogging and self-promotion and there are significantly more of them than people who may have different things to say for good reason. Note that right now, I am speaking generally, not debating a commit message approach.
> Then... you disagree with the "of course", you said.
No, the "of course" was: of course no one I work with would make that mistake (more than once). It would be an extremely beginner mistake, and we would have failed as coaches on our team to not pair with a person long enough to help them understand how to write proper commit messages.
> I'm going to assume that's a dependency version change.
Yes, it's a pinned version for that dependency. You don't have any context on that particular commit, so it's not surprising that it's ambiguous.
> Most theories are wrong, even by experts. It's not even embarrassing to be wrong.
Indeed! I have been wrong many times in my career. Hell, I invented the "auto-mocking container" which, in hind sight was so stupid (and btw, my colleague you referenced warned me about it at the time -- he's always been a few steps ahead) that I never should have popularized it. Thankfully, it fell into the past along with IoC containers (for the most part).
I have plenty of other stories about being wrong as well, and as I've said elsewhere, if we find a better way to write commit messages we will do that. For now, from our analysis, the way we do it is best for us -- observably (I'll say that, rather than objectively, though I do believe we were as objective as possible in our analysis).
Commit summaries are typically viewed as lists (though not always, and in that case you often have more context, e.g., the rest of the message and the diff)
We optimize them as we would list entries in any other thing we design for human consumption.
Btw, we didn't refer to these specific articles when we made our decision, I found them just now.
I updated my article with links to these. Thanks again for the discussion.
Error messages. Get to the meat of it in the first 3 words, there's a high chance that's the only part that will get read, or even displayed. It must be the most meaningful part of the error message.
I look at commit messages every day. I actually don't love a message that just describes the code change (I can figure that out on my own if I look at it long enough). That's fine for bigger or more misleading changes, but when I'm looking at blame/history I'm usually very aware of what the code is doing already. My question at those times is less about "what" and more about "why". Why was this change made? Sometimes that can be found by looking at accompanying tests (if the original author was so gracious), but if it's not in the commit (or only obtusely so, as many developers I know tend to commit in what I'll call "stream-of-consciousness" style) then I've got to go outside the codebase to research by interviewing people (assuming they're still around and remember) or trawling through our project management system to try and line up released features/fixes with the change. It quickly becomes an inexact science.
That said, in my experience, the larger an organization, the more commit messages get looked at. On my side projects where only 1-3 people are involved, commit messages only really show up on the PRs as things are going in. Sometimes we complete our own PRs to keep up the velocity since we're all working async part-time. Rarely if ever do we look back to figure out why we did something because the project is so small.
> My question at those times is less about "what" and more about "why". Why was this change made?
Isn't the essence of the commit message body to delve into the 'why'?
The ability to swiftly glean the 'what' from the commit subject line aids in identifying the appropriate commit for review. The commit message body can then have a detailed explanation of the reasons behind the change.
Putting "what" in the message can be fluff, in the same way repeating the code in a comment is fluff. But the broad strokes or considerations of the what may not be obvious from the diff. Expressing what the commit intends as prose can help with understanding, with discarding irrelevant change data, with post-mortem analysis, ...
It is also useful for conveying intent. If the commit message describes one thing, and the code does the opposite (or doesn't do it at all), that's something the "gatekeeper" can and should call out.
I've certainly sent out changes for review where I forgot to include a crucial file (or subdirectory).
About to say this as well, but would like to add. When I have a bug dealing with Foo in Bar, seeing a commit message like “Updated Foo to support Baz\nSee issue #123 for additional context. Also discussed in chat (link).” When looking for a recent bug, I’m going to review that commit immediately without having to do any bisecting/blaming. Easy peasy.
Mostly though, I tend to see just “support baz” as a commit message, which drives me bonkers.
What if only people that had context did reviewing? As in, what if when someone needed a review, it was their job to ensure that the reviewer had the context necessary. That is, it was "push" rather than "pull".
What if a team's process was set up in such a way that separate phase-gate reviews were not typically necessary. That is, the team tended to work in pairs where there was constant reviewing going on, and the team was practiced at pulling people in when necessary to review specific parts, e.g., things they had never done before or needed additional guidance on.
Do we all remember waterfall development? Where PMs would write specs, then they would throw those specs over the wall to devs, who would then throw code over the wall to testers? Does anyone feel like, perhaps, we've done it again with pull requests and we've started favoring asynchronous hand-offs, rather than one-piece-flow?
In bigger teams, scanning every diff instead of just the commit subject lines is significantly more time-consuming (a frequent activity in my experience).
I often decline proposed commits that lack concise, informative subject lines, and I hope other larger teams also do for efficiency and clarity. If that's considered gatekeeping, then I'm content to be one.
Understanding a diff usually requires knowing and remembering the codebase well, having a very clear code, the diff being reasonably short and atomic and time.
Commit messages, if good, are extremely helpful to check what changed e.g. in an open-source application you're using. Of course the commit messages can lie, so you should also check the diffs, but it's much easier to confirm what a diff does than deducing it.
Not to mention that for many changes you can only make a guess at what the intention was; if you have a message saying what was meant to be done, you can check that it really was done correctly.
1. I'm moving value from this address to that address through %rax register.
2. I'm copying this value from that place to that.
3. I'm making sure that this values are equal.
4. An invariant was broken and I need to restore it.
If you look at it, each next like is an answer to "why" question applied to a previous line. Answers to "why" questions becomes new "what" and then "why" applied to them again.
The point I want to make is it is easier to move back (in descending order) through this than forward. When you know (4) you can easily figure out what is needed to be done. But if you have (1) you need to infer next points one by one. One who just wrote the patch is probably unaware of differences, because he knows all the answers and can easily move from one to another. He/she do not feel difficulties. But the person who reads patch starts with (1) and needs to climb the ladder in opposite direction than the person who wrote the patch.
I agree with your first paragraph, but I don't think it's super relevant to the article: the why of a commit usually takes some time to explain, and the subject line is nowhere near sufficient, so that usually goes into the first paragraphs. For non-trivial commits I try to follow the "why, what, how" template: first explain the issue / concern / background for the change, then clarify the change if the diff is not super obvious or is a bit large, and finally explain the implementation changes if there were options.
In my experience the former and latter are the most important when blame-diving, I want to know the context / driving force / use case for a change, but I also want to know the scope of consideration, because e.g. sometimes I'm thinking of a fix which was considered and rejected for still-valid reasons, while at other times it was just considered unnecessary back then (YAGNI) or the blockers have since been removed.
Either way the subject needs to be snappy, so that it can quickly be selected for consideration or not e.g. if I'm blame diving and I see a commit which just does indenting / formatting, I probably can skip over it without looking at the actual change.
I mostly agree, though if I could only have “what” or “why” I would choose “why” every time. To me this is similar to describing the problem in product design. I wish the “why” was more often concise enough to be the prominent feature in a commit, because commits are difficult/annoying to amend (I’d be surprised if more than a couple people where I work knew how) and if something is going to be left out, it is the “why”.
Can't disagree with that. I think the order of importance is why > how > what, because the first two are the least likely / possible to infer from the commit contents. So an explicit record is most crucial.
Those are two very different things when it comes to commit messages.
For history, the linked argument is arguing that subject-first is better. Personally I'd prefer `[component] verb details` though, which should fix the skippability issues mentioned elsewhere. And of course you can enable diffstat to get a bit of an idea of the structure.
For blame, you have the full file context in front of you. Some blame frontends only show author, but assuming you have the commit message, what you really want out of it is a rough idea of the historical significance of that line. So definitely verbs first.
Spent 5 minutes trying to figure out where field_name is in the second list... I thought it was the same commits rewritten to be more scannable, but they are from a different project.
(I scanned, naturally, the article itself!)
Or more generally, I thought the point of the article would be that the function / variable names from the first list would be moved to the beginning of sentences. But in the 2nd example they are completely absent, favoring much vaguer / high level descriptions. So we are unable to see the before/after effect for the same list of commits, I think most of the potential impact of the author's intended point is lost.
(Also, the first half extolls the virtues of being able to read quickly, while the second half tells you to use longer sentences for everything for apparently no reason?)
Author here. I chose two real sets of commit messages rather than to fabricate one. Fabricating one may have made the second list easier to scan -- you'd already know what you were looking for and you would have some familiarity with the content. In any case, it's certainly not a perfect experiment or demonstration.
The specific function/variable names do not often make appearances in our commit messages (though they do sometimes, as do class names). They do, however, make very clear appearances in diffs. Commit messages stand on their own for their own purpose -- it's an index, and indexes are for scanning. If you need to read further, you zoom in.
Also, I wasn't trying to say to "use longer sentences for everything," where did you get that from? I offered some specific clarifications on how we write some common commit messages, and they may be longer than some alternatives, but our reasons are for clarity and consistency. We don't mind slightly longer commit messages, in large part because the first few words tend to be the most important.
The subject line says what the purpose of the change is (CI/CD, tests, bug fix, new feauture), what component it primarily focuses on, and then a plain text one line summary.
For example:
ci(GitLab): Add rust build directory to cache
This should improve build times by caching most of the compile tree between builds. In testing, I’ve observed builds drop from 2m to 30s when scheduled on a node with a primed cache.
It also forces me to keep my commits focused. If I can’t create a one line summary of what I’ve done, it probably needs to be broken up into multiple commits.
feat is just the short form of feature; chore is for annoying stuff like fixing lint issues or maybe package updates that don't require any code changes etc... those are the little chores we do to keep everything flowing.
It is irrational, but "feat" tells me the change is a marvel, something to be looked at. Webster says "an act or product of skill". Nah, it's a feature. "feat" sounds pompous. Shout it from the rooftops: everyone, this is a feat! Not a small feat. Aah. Feat.
"chore" is too vague for me. A "feat" can be a "chore" if I don't want to work on it. "chore"-s like the one you describe are occasionally feats (the no-quote kind).
"feat" is something that adds value to product's end users. The things we put on release notes. "chore" is something that adds value to the engineering team. The things we have to do to keep being productive.
Conventional commits are great, especially if you add in commit linting.
Being able to programmatically increment semantic versions and automatically generate relevant changelogs is awesome.
It’s also nice to implement Commitizen[0] for a little hand holding until folks get used to the linting.
I used to care a lot about doing things the way that felt right to me, but now I just want some common standard that is easy for everyone to follow, easy to automate, and easy to verify programmatically.
Things like conventional commits and semantic versioning aren’t perfect, but they are quite good and apply broadly to many use cases with common tooling and conventions.
eg:
cocoaui: fix images being incorrectly aligned on high dpi displays
We were calculating the position of the image in logical pixels, but not converting that to actual display pixels for rendering.
I think it's a really nice style that makes commit messages really easy to scan in a short log, and lets you ignore commits easily that don't touch the area you're interested in
I’m against any style or enforcement of style of commit messages that breaks changelog
I use git log history for changelogs with a little dressing for markdown. I could pull this from Jira but it’s worse. Stories aren’t changes.
So I understand that some folks use git log for history and care about their code style so much as to enforce commit message stylecop, it’s overkill in my world and would only cause you to have to amend your commit or write a new message on squash.
The subject-first style felt grating at first, but comparing the two I found myself reading more per line than I did in the verb-first approach.
Fix skip fix skip fix skip add skip
I knew nothing at the end. The second style had me grasp more, as there were no obvious hooks to skip without knowing what had changed.
But as others have said, commit messages are a cesspool of bikeshedding and ultimately useless, unless every commit is a self-contained chunk of work which it rarely is.
On the side, I enjoyed all of this author's thoughts in the repo. Good find.
Author here. Thank you! I agree that there can be plenty of bike shedding about them, which is why we have an approach that is based on human psychology and can be backed up in that way. We don't often put too much more in the content of a commit message -- the diff, plus the repo it's in (we have many repos) tell you most what what you need to know.
If you want more context, every team member has a daily work log that is available to the entire team, so you can see more about what they worked on and why in that work log.
> I agree that there can be plenty of bike shedding about them, which is why we have an approach that is based on human psychology and can be backed up in that way.
You optimized for a micro benchmark and presented no data.
It was a design decision, and like most design decisions, it was based on first principles and a-priori knowledge. If we had to base all of our design decisions on data and benchmarks, we wouldn’t be able to design anything. I can assure you, that if a better format with better properties came around, we would likely switch to it (assuming we accounted for switching cost and the variation we would be introducing).
> The second style likely feels foreign, and possibly uncomfortable. It's passive voice and present tense — all the things that we aren't supposed to make our commit messages.
Nitpick: it's passive voice and indicative mood (and sometimes subjunctive) -- there's nothing wrong with present tense. "Fix typo" is active voice, present tense, and imperative mood. (The Rails commits that dip into past tense bother me slightly, but whatever.)
Broadly, I have a few opinions on commit messages. The style doesn't really matter as much to me, although I'm a relatively strong adherent to "one-line summary, followed by paragraph(s) of additional context" (as is
standard in the Linux kernel, and supposed best practice at Google even if it isn't universal by a long shot).
One is that the commit message should be useful for anchoring a search for potentially relevant changes, and for providing broader context re: why the change was made.
At the same time, I waffle between putting more description in the commit message, versus just commenting the code (or making the code clearer).
The last is more pragmatic: when I'm searching for a specific change, I'm often looking at the history of a particular file (blame or otherwise). I can quickly filter out all the "fix typo" messages or "[LSC]" (large-scale change, term used at Google for various company-wide code health refactors). Or if I'm trying to figure out which change introduced a bug, I'll probably bisect it one way or another (I often try to short-circuit that bisection toward the end to save the last few iterations). Either way, I don't actually spend that much time reading through commit messages until I've identified a potentially problematic change.
We don't tend to put much in the commit messages themselves. The code often speaks for itself (and if it doesn't, it isn't likely that the author would have had much more to say about it at the time, as our norm is to comment "why" when necessary). We also have work logs we can refer to that sometimes have the why, or at least some of the context for the work we are better trying to understand.
- Blame view, where I usually want to know the ticket number so I can track down a story which has the business rules the dev was implementing.
- Bisect, where I want to know if this works or not without having to do a test run every time.
This format is alright I guess, but the best thing you can do honestly is just
TICKET: [done/works but wip/does not work] [describe what you’re thinking]
AB-1234: does not work, trying to rewrite this controller to remove all the duplication, /api removed temporarily
To me, that doesn’t have to be set in stone. No one likes working with a commit message stickler when standardized formats are only useful ~20 times a year to save 10 minutes each. (In my experience)
The problem with the experiment is that when I’m scanning, typically I’m never scanning and then getting tested on the contents after the fact. It actually took me longer to spot any mention of store in the second example after being told what I was looking for than it did for me to find field_name after being told to look for it. YMMV.
Author here. Commits aren't actions -- they are a log of an action being taken. You, the committer, are committing. What you commit, goes into a commit log. We choose to make our commit messages describe the change, rather than the person that made the change. It's about the work, not the worker.
I'm trying to imagine my commits coming alive and doing things to my code. I think you may be taking the "When this commit is merged..." thing a bit far, as commits don't actually do anything. They just are. We don't tend to do ourselves any services by anthropomorphizing aspects of our work. I'm happy to concede that we see things very differently.
I was responding to the author of the comment I was responding to, who was anthropomorphizing the commit itself claiming that it did something.
I agree that the person who write the code is irrelevant, though I realize that in a different way. I also recognize that it varies from Git/Linux/etc. We do it for usability and other reasons and one only needs to look at git itself to recognize that the original authors did not have usability in mind when designing it. What they built is incredibly powerful, but it's rare for usability and technical prowess to overlap.
> I was responding to the author of the comment I was responding to, who was anthropomorphizing the commit itself claiming that it did something.
Uh huh. The comment that you replied to is pretty much in line with the wider “patch does X to the code” which isn’t about anthropomorphizing. That’s the spin that you put on it.
It’s about as much anthrop. as saying that a falling piano crushed someone’s leg.
> We do it for usability and other reasons and one only needs to look at git itself to recognize that the original authors did not have usability in mind when designing it. What they built is incredibly powerful, but it's rare for usability and technical prowess to overlap.
It’s also rare to find commit message quality that is on the level of the regular contributors to that project. Which has nothing to do with how unfortunate the UX of the tool is.
Again, I was responding to this particular text: "And the work does an action on the code." You can interpret that the way that you interpret it. I saw it as a part of a wider tendency in the development community and responded to it accordingly. Perhaps it wasn't what was intended. At this point, it's rather a distraction so I'm happy to concede that it is ambiguous and the author was likely attempting to describe the common "When applied, this commit will..." inferred prefix.
> It’s also rare to find commit message quality that is on the level of the regular contributors to that project
I prefer the first style. It reads way less weirdly. I spend way more time reading commit messages than "manually searching" by scanning them. I either arrive at the commit from git blame, or I use this really cool feature of computers called "ctrl-F".
Ehhh... maybe. One implicit trade-off here is how low detail the second set is, and that'll happen any time you force a structure - mandated structure takes more space on average, sometimes significantly more. Passive voice wastes a lot of space too (in English anyway).
Personally I think this is better solved by a changelog doc (which you can wordsmith for outsiders, which is an entirely different target than internal developers) and `git blame` (I never browse all of history to find changes to a method, just blame it for the latest or `git log -p -L` to check a series of changes to a file/func/etc).
174 comments
[ 2.7 ms ] story [ 249 ms ] threadAnd also the discourse around commit messages and their various flavors may be one of the biggest wastes of time in terms of ROI in our industry.
I’ve been doing this for 14-15 years and can probably count on two hands the number of times I’ve needed to look at historical commit messages.
I agree that when I did PRs I didn’t tend to care about the commit messages when I was reviewing them, but even when I did do PRs I cared about them later any time I was trying to understand how, why, or who forensically.
I wonder what is so different about our workflows, that some people do it all the time and others almost never.
Are we working on somehow very different things.
To me I find that code is the source of truth and current state, it doesn't really matter to me as much why or how something came to be as I look more into how I can make the current thing work with what I am to do.
Or simply the projects you work with have poor commit messages?
I would say however that the commit messages mostly are just squashed pull requests with ticket names and single sentence so I'd agree that they wouldn't be very good for that purpose, but I don't see anyone at the org complaining about this.
It's mostly on the Internet I read how others use the git history, but I haven't seen anyone really doing a lot of that in real life.
There’s your answer.
That said, there's probably some fringe benefit to describing what you do in some fashion. It's a great way of making sure you understand what's happening yourself.
Deducing lost information (or trying to deduce it) often takes enormously much more effort than what it takes to write it down.
It’s not like you need the history (is this a refactor or something else? doesn’t matter) so you don’t need to keep around such failed attempts.
Having said that, I care very little about style and grammar of commit messages. Ideally I want them to say why the change was made, what the intended effect was, and where I can look for related work (bugs that tracked the work and have related commits or investigation attached to them, docs, whatever)
Hit rate on the information I'd like is not great, but if I get at least one of the three things then it's something I can work with.
What I normally do is, while investigating a tricky bug and finding some lines that don't make sense, look through history to see why those lines were introduced (to see if they fix something else), and perhaps when (to see which versions may be affected by a hard-to-reproduce bug). But that typically pinpoint a commit already, and I just need the commit message to explain why it was there.
I see it as a matter of scoping communications. The issue management system includes a broader set of people than the git repo. You want the commit linked to the issue so that you can see the entire history behind the commit, including the business decisions, the designer making a call, the back and forth with QA etc. That can all be useful a year or two down the road if you want to understand why something was done a certain way.
Now there is some info about the change that perhaps only the devs would ever care about, and probably that can sit in the commit messages. That sort of happens naturally but there's not really a lot of it for us. But that seems to me to be the relevant thing from an organizational perspective, no one writes commit messages except for devs, and almost nobody except the devs reads them.
I think that breaks the thing that people want which is being able to `git commit -m "Fix #234353"` without a body at all.
`git commit -m "Fix actual words that humans read" -m "Fixes: #234353"`
You could probably script this based on branch if you're one of those people who names branches after ticket numbers.
But my actual advice is that I think -m is a bad pattern that leads to bad commit messages, and omitting the message argument opens your EDITOR, and you should use that.
Commit messages have only ever been useful in tracking my own intermediate work products. Often times, I will leave helpful bread crumbs in my commit notes if I know I won't be working on something for a few days. We strictly do squash+merge, so I don't have to worry about these things causing trouble for others. All of our commits into master have some standardized "Issue #1234" note as automatically copied from the PR title (which we do have ~standardized).
If we didnt have some git wrapper like GitHub available, then I suspect we'd be significantly more aggressive with policy around our commit messages.
Which is a very interesting take, for what it's worth. Might be worth a blog post what circumstances lead to this working well for your organization!
- review feedback format
- variable naming
- keeping line lengths to 80 lines
- log message formats (sweet jesus the amount of time wasted debating that alone)
Whenever I see these conventions about commit formatting they generally seem to focus on the first line (notable exceptions being Git and the Linux kernel among others I assume), one line is rarely enough to describe the change – I’m not advocating for writing an essay for a 5 line change though in some cases it might be warranted.
Professionally I rarely see useful commit messages, by useful I mean something that could be read by someone without context and get a general understanding of why a change was made. Frequently I have seen “updates” / “wip” etc. in the master branch. More frequently I see that the quality of commit message decreases with an engineer’s seniority – though like every thing there are exceptions.
verb-first commits can be organised in a few categories. since they are few commit verbs (fix, add, refact..), always use the same verb prefix for bug, features messages and you will have nice categories to scan/filter:
- add feature
- fix bug
- refactor logic
On the other hand, subject-first indeed put the important part first and let you search for a term:
- Instance configure template method called from constructor
- Store's project method is an alias for fetch
- Title is changed
Depending on the use case, are you often searching for something? or would you like to highligh the nb of bugs/features in the last release?, one style is better suited than the other.
For important changes, I like the linux kernel style: oneline summary, details (problem, impact, solution..)
https://docs.kernel.org/process/submitting-patches.html
[1] https://www.conventionalcommits.org/en/v1.0.0/
I find this way WAY harder to read/scan, and very much prefer Google's standard: https://google.github.io/eng-practices/review/developer/cl-d...
It's called a change list even though it's a single commit because Perforce tracks changes per file, so if you modify multiple files in a single commit, you are introducing a list of changes in their model.
What's your evidence or supporting research?
> things are easier to scan if the more important part is first
You skipped the step where "most important" is defined.
> "Specifier can be configured when constructing a store"
This is just about the worst type of commit message, in my opinion, only marginally better than an empty commit message.
Ok. Specifier can be configured when constructing a store. Is it supposed to? Is it the state before or after the commit? Is this just context, and maybe this commit changes documentation to reflect that reality?
You even say that reading a bunch of them is uncomfortable.
> It's not about the self. It's about the code.
Actually, it's about the change. When something broke, what changed. When a new release comes out, what changed.
Some people prefer the past form "Added feature X" instead of "Add feature X". On that I just say "be consistent".
Also note that your first batch of examples are inconsistent. "Whitespaces", "We don't use `::` to denote class methods", "Avoid __method__", past/present verb form, etc. The difference isn't just the form, but whether commits actually follow any style at all.
> I eventually recognized the benefit of scannability
Scannability is hugely important. People who disagree with your style of commit message don't disagree with you on that.
> For example, "Widget tests" is preferred over "Widget tests are added".
What about the widget tests?
> When describing a version increase, be explicit about both the old and the new version. E.g., "Package version is increased from 1.1.1 to 1.2.0"
Are version numbers ever decreased?
(1.1.2 can be released after 1.2.0, yes, but that's not a decrease even if something was backported)
We didn't need it. It was based on a-priori knowledge. For example, we don't write email subjects like: "Convey information about new release", or "Ask question about time off". We know from how the human brain processes content (eye tracking studies) that they scan in an F-shaped pattern. This puts emphasis on the content on the left. If the left side has no differentiation, this is, de facto, harder to scan.
You don't have to agree with me. As my colleague said, there are other, even more subtle things we are trying to convey and reinforce: https://news.ycombinator.com/item?id=38836919
> You skipped the step where "most important" is defined.
No, we literally do this every time we write a commit message. This is a usability issue. What is the most important thing to the reader?
> Ok. Specifier can be configured when constructing a store. Is it supposed to? Is it the state before or after the commit? Is this just context, and maybe this commit changes documentation to reflect that reality?
And yet, when all of your commit messages are in a consistent voice and mood, there is no ambiguity. Also, all of your questions are answerable from a self-evident perspective -- if you can rely on your teammates to care about your ability to understand what they write. Of course it's supposed to, otherwise why would I commit it? Of course it's the state after the commit, why would I talk about what was (How many newspaper articles about a celebrity's death have a headline saying they are sick?)? Of course it's not about documentation, it would say it was if it was. In short, you can make up as many holes as you want to poke through.
> You even say that reading a bunch of them is uncomfortable.
I said at first. See: familiarity bias
> What about the widget tests?
This is convention that one could argue requires memorization. I don't actually think it does, however, because of how we as humans interpret subjects/headlines.
> Are version numbers ever decreased?
They have been, and I hope it's self-evident how that commit message would be constructed on our project.
In any case, I'm not here to quibble about commit message formats. I documented ours and gave supporting rationale which is based on UX knowledge (and research, at the very least, see eye tracking studies). If you think that "Fix", "Fix", "Add", "Change", are the most important part of the commit message, then I'm not really going to be able to or even bother trying to convince you otherwise.
Well, you may hold these truths to be self-evident, but that's hardly an argument. And since you say "It's likely what your team uses, as it is the commit message style that is typically recommended as a "best practice" you acknowledge that you hold a minority opinion.
"What I'm saying is self-evidently true" is unlikely to sway anyone.
And I find it dishonest to phrase that as "The psychology portion isn't subjective".
From your colleague:
> The reason that the "subject-first" approach is used is to get contributors to talk specifically to the impacts made to the software itself, rather than talk about themselves and their labors.
I don't recognize that description at all about the majority opinion. Yes, some people write terrible commit messages, but that's not the best practice you seek to upend.
> Of course it's the state after the commit, why would I talk about what was
You'd be surprised. It's more common in bug reports, but I've seen this in commit messages too.
>> Are version numbers ever decreased? > They have been,
Oh, really? Do you have an example?
> In any case, I'm not here to quibble about commit message formats.
Thanks for clarifying that you base this policy on nothing but your subjective opinion, that there is no research to support it, and that everyone else is doing it wrong, because your subjective is clearly objective.
Nothing wrong with that. I do have a problem with you misrepresenting this as objectively better, with a handwavy "scan in F shape". Don't say it's based on research when it's just your "common sense". That's unprofessional.
An opinion being minority has no reflection on whether or not it is correct. See hand washing in the medical profession before it was understood, or batch sizes in the automobile industry before Toyota ate the west's lunch.
> And I find it dishonest to phrase that as "The psychology portion isn't subjective".
You can find it dishonest if you wish, but I'm trying to point to a body of knowledge I can't adequately convey in an article or a hackernews comment. I'm not trying to pull one over on you, I promise. As I said in another response, this is a design decision. Most design decisions are based on first principles, a-priori knowledge, expertise, a wide range of studies and observations over time, etc. If a person can't write down (convincingly) all of the tacit knowledge required to make the same decision, they are not being dishonest.
I'll say it this way: We made this decision based on objective factors. I do not expect everyone to be able to see our decision or our reasons in the same objective light and I'm not going to try to convince someone that doesn't. But telling me it's purely subjective is gaslighting, and impugning my integrity over it is just rude.
> You'd be surprised.
No, I wouldn't. I would be surprised to see it on our team, or any other well-disciplined team. This article is a tiny (and frankly pedestrian) part of our overall development process. I'm sure you'd disagree with just about everything else that we do as well, and that's OK as well.
> Oh, really? Do you have an example?
Sure:
mail package version is decreased from 2.8.0 to 2.7.1
This happened when we were forced to pin to an older version of the mail gem because of a regression in 2.8.0.
Note that the scenario you described: "(1.1.2 can be released after 1.2.0, yes, but that's not a decrease even if something was backported)" isn't relevant to our practice. We don't maintain multiple major/minor versions at one time of any of our packages. If we did, they would be on separate branches as the version number can only exist in one place (the gemspec) and the same exact rules would apply. That is, it wouldn't be a version decrease, it would be an increase from 1.1.1 to 1.1.2 on the 1.1 branch.
I entirely agree. But if you find yourself in the minority, then I encourage you to objectively consider what's more likely: Are you right, or are most other people right? Or maybe there is no right and wrong (aside from being consistent)?
Sometimes the minority is right. But usually that's not the case.
> See hand washing in the medical profession before it was understood.
Ooookayy. I would not compare any technical decision in this space to that. A bit grandiose. More traditionally one says "10k flies can't be wrong: poop must taste great!".
> If a person can't write down (convincingly) all of the tacit knowledge required to make the same decision, they are not being dishonest.
I agree. As long as they don't claim otherwise. I'm sure you're an expert, with lots of experience. Experience that creates a good judgement, and good intuition. But that also describes the majority of the experts, who, turns out, disagree with you.
>> You'd be surprised. > No, I wouldn't.
Then... you disagree with the "of course", you said.
> mail package version is decreased from 2.8.0 to 2.7.1
What does that mean? A dependency version decrease? If this is a commit on the mail package itself, then what does it mean?
I'm going to assume that's a dependency version change.
"10k flies can't be wrong" is one thing, but "the majority expert opinion in my field is wrong"... is almost always wrong.
Most theories are wrong, even by experts. It's not even embarrassing to be wrong.
But to defend your policy on objective grounds, is like asserting Ruby should be used for all programming. It's Not Even Wrong. https://en.wikipedia.org/wiki/Not_even_wrong
One has to be able to understand an analogy for the point the person is trying to make -- it's not an equivalence. Obviously most software issues don't rise to the level of life or death.
That said, let's try a few others:
- Waterfall
- DCOM
- CORBA
- Web Services
- Microservices (as implemented by web developers -- per-entity web api to web api to web api cascading failure)
- Monorepos (not globally, with sufficient support these can work)
- Devs shouldn't write tests
- Fat Model, Skinny Controller
- Write tests. Not too many. Mostly integration.
- Single Page Apps for all
- SCRUM
- Story points
Most, if not all of those were embraced by "most experts", but are now demonstrated problematic or at least are knowably wrong from fundamental design principles. Note that statistically speaking, "most experts" are, at best, early majority. There aren't very many in the Innovators and Early Adopters, and crossing that chasm is rare, and hard.
We have a history in our community of intransigence, repeating mistakes, and expert beginners being the most outspoken portion of our community. They are the ones that have the most to gain by blogging and self-promotion and there are significantly more of them than people who may have different things to say for good reason. Note that right now, I am speaking generally, not debating a commit message approach.
> Then... you disagree with the "of course", you said.
No, the "of course" was: of course no one I work with would make that mistake (more than once). It would be an extremely beginner mistake, and we would have failed as coaches on our team to not pair with a person long enough to help them understand how to write proper commit messages.
> I'm going to assume that's a dependency version change.
Yes, it's a pinned version for that dependency. You don't have any context on that particular commit, so it's not surprising that it's ambiguous.
> Most theories are wrong, even by experts. It's not even embarrassing to be wrong.
Indeed! I have been wrong many times in my career. Hell, I invented the "auto-mocking container" which, in hind sight was so stupid (and btw, my colleague you referenced warned me about it at the time -- he's always been a few steps ahead) that I never should have popularized it. Thankfully, it fell into the past along with IoC containers (for the most part).
I have plenty of other stories about being wrong as well, and as I've said elsewhere, if we find a better way to write commit messages we will do that. For now, from our analysis, the way we do it is best for us -- observably (I'll say that, rather than objectively, though I do believe we were as objective as possible in our analysis).
Thanks for the discussion.
https://www.nngroup.com/articles/first-2-words-a-signal-for-...
https://www.nngroup.com/articles/text-scanning-patterns-eyet...
https://www.nngroup.com/articles/list-entries/
Commit summaries are typically viewed as lists (though not always, and in that case you often have more context, e.g., the rest of the message and the diff)
We optimize them as we would list entries in any other thing we design for human consumption.
Btw, we didn't refer to these specific articles when we made our decision, I found them just now.
I updated my article with links to these. Thanks again for the discussion.
That said, in my experience, the larger an organization, the more commit messages get looked at. On my side projects where only 1-3 people are involved, commit messages only really show up on the PRs as things are going in. Sometimes we complete our own PRs to keep up the velocity since we're all working async part-time. Rarely if ever do we look back to figure out why we did something because the project is so small.
Isn't the essence of the commit message body to delve into the 'why'?
The ability to swiftly glean the 'what' from the commit subject line aids in identifying the appropriate commit for review. The commit message body can then have a detailed explanation of the reasons behind the change.
Putting "what" in the message can be fluff, in the same way repeating the code in a comment is fluff. But the broad strokes or considerations of the what may not be obvious from the diff. Expressing what the commit intends as prose can help with understanding, with discarding irrelevant change data, with post-mortem analysis, ...
I've certainly sent out changes for review where I forgot to include a crucial file (or subdirectory).
Mostly though, I tend to see just “support baz” as a commit message, which drives me bonkers.
What if only people that had context did reviewing? As in, what if when someone needed a review, it was their job to ensure that the reviewer had the context necessary. That is, it was "push" rather than "pull".
What if a team's process was set up in such a way that separate phase-gate reviews were not typically necessary. That is, the team tended to work in pairs where there was constant reviewing going on, and the team was practiced at pulling people in when necessary to review specific parts, e.g., things they had never done before or needed additional guidance on.
Do we all remember waterfall development? Where PMs would write specs, then they would throw those specs over the wall to devs, who would then throw code over the wall to testers? Does anyone feel like, perhaps, we've done it again with pull requests and we've started favoring asynchronous hand-offs, rather than one-piece-flow?
I often decline proposed commits that lack concise, informative subject lines, and I hope other larger teams also do for efficiency and clarity. If that's considered gatekeeping, then I'm content to be one.
Commit messages, if good, are extremely helpful to check what changed e.g. in an open-source application you're using. Of course the commit messages can lie, so you should also check the diffs, but it's much easier to confirm what a diff does than deducing it.
Not to mention that for many changes you can only make a guess at what the intention was; if you have a message saying what was meant to be done, you can check that it really was done correctly.
1. I'm moving value from this address to that address through %rax register.
2. I'm copying this value from that place to that.
3. I'm making sure that this values are equal.
4. An invariant was broken and I need to restore it.
If you look at it, each next like is an answer to "why" question applied to a previous line. Answers to "why" questions becomes new "what" and then "why" applied to them again.
The point I want to make is it is easier to move back (in descending order) through this than forward. When you know (4) you can easily figure out what is needed to be done. But if you have (1) you need to infer next points one by one. One who just wrote the patch is probably unaware of differences, because he knows all the answers and can easily move from one to another. He/she do not feel difficulties. But the person who reads patch starts with (1) and needs to climb the ladder in opposite direction than the person who wrote the patch.
In my experience the former and latter are the most important when blame-diving, I want to know the context / driving force / use case for a change, but I also want to know the scope of consideration, because e.g. sometimes I'm thinking of a fix which was considered and rejected for still-valid reasons, while at other times it was just considered unnecessary back then (YAGNI) or the blockers have since been removed.
Either way the subject needs to be snappy, so that it can quickly be selected for consideration or not e.g. if I'm blame diving and I see a commit which just does indenting / formatting, I probably can skip over it without looking at the actual change.
Those are two very different things when it comes to commit messages.
For history, the linked argument is arguing that subject-first is better. Personally I'd prefer `[component] verb details` though, which should fix the skippability issues mentioned elsewhere. And of course you can enable diffstat to get a bit of an idea of the structure.
For blame, you have the full file context in front of you. Some blame frontends only show author, but assuming you have the commit message, what you really want out of it is a rough idea of the historical significance of that line. So definitely verbs first.
Isn't the point of the commit message title precisely that you don't have to look at it long enough?
(I scanned, naturally, the article itself!)
Or more generally, I thought the point of the article would be that the function / variable names from the first list would be moved to the beginning of sentences. But in the 2nd example they are completely absent, favoring much vaguer / high level descriptions. So we are unable to see the before/after effect for the same list of commits, I think most of the potential impact of the author's intended point is lost.
(Also, the first half extolls the virtues of being able to read quickly, while the second half tells you to use longer sentences for everything for apparently no reason?)
The specific function/variable names do not often make appearances in our commit messages (though they do sometimes, as do class names). They do, however, make very clear appearances in diffs. Commit messages stand on their own for their own purpose -- it's an index, and indexes are for scanning. If you need to read further, you zoom in.
Also, I wasn't trying to say to "use longer sentences for everything," where did you get that from? I offered some specific clarifications on how we write some common commit messages, and they may be longer than some alternatives, but our reasons are for clarity and consistency. We don't mind slightly longer commit messages, in large part because the first few words tend to be the most important.
https://www.conventionalcommits.org/en/v1.0.0/
The subject line says what the purpose of the change is (CI/CD, tests, bug fix, new feauture), what component it primarily focuses on, and then a plain text one line summary.
For example:
It also forces me to keep my commits focused. If I can’t create a one line summary of what I’ve done, it probably needs to be broken up into multiple commits."chore" is too vague for me. A "feat" can be a "chore" if I don't want to work on it. "chore"-s like the one you describe are occasionally feats (the no-quote kind).
Oh well.
Being able to programmatically increment semantic versions and automatically generate relevant changelogs is awesome.
It’s also nice to implement Commitizen[0] for a little hand holding until folks get used to the linting.
I used to care a lot about doing things the way that felt right to me, but now I just want some common standard that is easy for everyone to follow, easy to automate, and easy to verify programmatically.
Things like conventional commits and semantic versioning aren’t perfect, but they are quite good and apply broadly to many use cases with common tooling and conventions.
--
[0]: http://commitizen.github.io/cz-cli/
codebase section: short summary
longer description if necessary
eg: cocoaui: fix images being incorrectly aligned on high dpi displays
We were calculating the position of the image in logical pixels, but not converting that to actual display pixels for rendering.
I think it's a really nice style that makes commit messages really easy to scan in a short log, and lets you ignore commits easily that don't touch the area you're interested in
I use git log history for changelogs with a little dressing for markdown. I could pull this from Jira but it’s worse. Stories aren’t changes.
So I understand that some folks use git log for history and care about their code style so much as to enforce commit message stylecop, it’s overkill in my world and would only cause you to have to amend your commit or write a new message on squash.
Fix skip fix skip fix skip add skip
I knew nothing at the end. The second style had me grasp more, as there were no obvious hooks to skip without knowing what had changed.
But as others have said, commit messages are a cesspool of bikeshedding and ultimately useless, unless every commit is a self-contained chunk of work which it rarely is.
On the side, I enjoyed all of this author's thoughts in the repo. Good find.
If you want more context, every team member has a daily work log that is available to the entire team, so you can see more about what they worked on and why in that work log.
You optimized for a micro benchmark and presented no data.
Nitpick: it's passive voice and indicative mood (and sometimes subjunctive) -- there's nothing wrong with present tense. "Fix typo" is active voice, present tense, and imperative mood. (The Rails commits that dip into past tense bother me slightly, but whatever.)
Broadly, I have a few opinions on commit messages. The style doesn't really matter as much to me, although I'm a relatively strong adherent to "one-line summary, followed by paragraph(s) of additional context" (as is standard in the Linux kernel, and supposed best practice at Google even if it isn't universal by a long shot).
One is that the commit message should be useful for anchoring a search for potentially relevant changes, and for providing broader context re: why the change was made.
At the same time, I waffle between putting more description in the commit message, versus just commenting the code (or making the code clearer).
The last is more pragmatic: when I'm searching for a specific change, I'm often looking at the history of a particular file (blame or otherwise). I can quickly filter out all the "fix typo" messages or "[LSC]" (large-scale change, term used at Google for various company-wide code health refactors). Or if I'm trying to figure out which change introduced a bug, I'll probably bisect it one way or another (I often try to short-circuit that bisection toward the end to save the last few iterations). Either way, I don't actually spend that much time reading through commit messages until I've identified a potentially problematic change.
We don't tend to put much in the commit messages themselves. The code often speaks for itself (and if it doesn't, it isn't likely that the author would have had much more to say about it at the time, as our norm is to comment "why" when necessary). We also have work logs we can refer to that sometimes have the why, or at least some of the context for the work we are better trying to understand.
- Blame view, where I usually want to know the ticket number so I can track down a story which has the business rules the dev was implementing.
- Bisect, where I want to know if this works or not without having to do a test run every time.
This format is alright I guess, but the best thing you can do honestly is just
TICKET: [done/works but wip/does not work] [describe what you’re thinking]
AB-1234: does not work, trying to rewrite this controller to remove all the duplication, /api removed temporarily
To me, that doesn’t have to be set in stone. No one likes working with a commit message stickler when standardized formats are only useful ~20 times a year to save 10 minutes each. (In my experience)
Commits are actions and should place actions first.
If you need to find a specific item, that is what `git log --grep` is for.
In essence, I think of commits as edges in a graph between nodes, and the nodes are the repo state.
So to me, commits are a state transition; this is why they do something to the code, at least to me.
I agree that the person who write the code is irrelevant, though I realize that in a different way. I also recognize that it varies from Git/Linux/etc. We do it for usability and other reasons and one only needs to look at git itself to recognize that the original authors did not have usability in mind when designing it. What they built is incredibly powerful, but it's rare for usability and technical prowess to overlap.
Uh huh. The comment that you replied to is pretty much in line with the wider “patch does X to the code” which isn’t about anthropomorphizing. That’s the spin that you put on it.
It’s about as much anthrop. as saying that a falling piano crushed someone’s leg.
> We do it for usability and other reasons and one only needs to look at git itself to recognize that the original authors did not have usability in mind when designing it. What they built is incredibly powerful, but it's rare for usability and technical prowess to overlap.
It’s also rare to find commit message quality that is on the level of the regular contributors to that project. Which has nothing to do with how unfortunate the UX of the tool is.
> It’s also rare to find commit message quality that is on the level of the regular contributors to that project
Good stuff, I'll take a look at it. Thanks!
Personally I think this is better solved by a changelog doc (which you can wordsmith for outsiders, which is an entirely different target than internal developers) and `git blame` (I never browse all of history to find changes to a method, just blame it for the latest or `git log -p -L` to check a series of changes to a file/func/etc).