The Lost Art of Commit Messages

35 points by drac89 3 months ago | 59 comments
  • saagarjha 3 months ago

      Reject commit message suggestions
      
      When working on large software projects, commit messages that follow
      the format suggested by the author rarely provide additional value.
      Having commits prefixed by "chore:" or "docs(ui):" aren't that useful.
      Instead, some of those 50 characters can be used for more descriptive
      titles. Commit messages are often the best and only context available
      when bisecting a bug, so bullet points only really make sense when
      making a list. Prose works just fine.
      
      Writing styles vary across contributors but it's much more useful to
      get *anything* from someone in their preferred format than nothing at
      all because they are frustrated with rules. Some committers do have a
      special "committer voice" that they use when describing complex changes
      in a commit message. For example, the text here is slightly abridged
      and focuses less on the first person than what is typically expected.
      This evolves naturally from writing these.
      
      Finally, commit comments definitely should have jokes in them. This is
      actually more critical than wrapping them at 72 characters.
    • tux3 3 months ago
      The author is working in an environment where, left to their own device and allowed free form messages, programmers write the three word sentences shown in the blog post.

      This is the downside of the variation in style across contributors. It works if people want to build something, and not just do the minimum. Open source projects frequently have no such limitations.

      But I am sad to report that some people appear to need the structure.

      • saagarjha 3 months ago

          Address structural issue with code contributions
          
          In some cases, it's possible to end up with commit messages that carry
          very little value. Unfortunately, while the minimum is clearly
          insufficient, it is possible to "expand" the minimum into a specific
          format without substantially improving the quality of the commit
          message. For example, a substantial refactor can easily just be
          described as a list of the changes that it included, rather than a
          rationale for why it was done (which is not readily apparent from the
          change itself).
          
          In the long run, problems involving people can be improved by process,
          but cannot wholly be solved by them. Pernicious failures need to be
          acted upon directly. Demonstrating the value of good commit messages is
          often a better driver of improvements than a template that is a chore
          to fill out.
        • MrJohz 3 months ago
          In my experience, people write overly short commit messages when they're writing too many commit messages. The solution is usually not to teach people to write better commit messages (although that's also good), but to teach them how to group and bundle commits together to create a meaningful standalone patch.

          One of the easiest ways to start there is to adopt PR-based review systems, where any number of commits can get pushed to a git repository and then reviewed as a single block. This is fairly inflexible, but it is very simple to get started with (no need to learn any special rebasing commands, just add, commit, add, commit, push). Most git forges allow you to do squash merges, so everything in the PR will become a single commit, usually with the PR description as a commit message. Then you can refine the commit and commit message during the review process.

          There are better tools out there, but in my experience, this is the quickest way to get started for most teams, especially as you're probably already using a forge that allows you to do all of this already.

        • chrismorgan 3 months ago

            Also, reconsider column-based hard-wrapping entirely,
            and consider wrapping mostly on punctuation,
            or other reasonable opportunities when it gets a bit long
            and you don’t really want to insert punctuation.
          
            This is not without its drawbacks and limitations—
            most software when rewrapping won’t cope with trailing em dashes,
            and you’ll end up with extraneous spaces when the lines are merged,
            even though this is *always* how wrapping has worked around dashes.
          
            Over time, this will definitely influence your writing style.
            Your sense of æsthetics will push you to reword sentences,
            because otherwise the edge is too ragged for your liking,
            and at some point you’ll see a pattern in a paragraph,
            and feel an uncontrollable urge to continue it,
            and you’ll waste a bunch of time tweaking,
            and maybe no one will appreciate it.
            But you’ll appreciate it.
            It’ll be fun.
            Mostly.
          
            But seriously, you *will* become more aware of things like clause length,
            and your writing will probably improve.
          
            And after writing verbosely for a long time,
            you’ll focus on concision,
            and that’ll be another challenge.
            And it’ll be fun too.
            Mostly.
          
            Then probably someone will take over your pet docs project,
            and mandate an autoformatter that rewraps it to 59 columns.
            Stubbornly, in the quiet of your mind, you’ll make it work.
            It’s a greater challenge, but you won’t lack determination.
            Style guides come, and style guides go; when this one goes,
            your lines can remain the same, needing no fixing, perfect.
          
            —⁂—
          
            And really, just look at how the last paragraph of the parent comment looks,
            before and after:
          
                Finally, commit comments definitely should have jokes in them. This is
                actually more critical than wrapping them at 72 characters.
          
                                                —⁂—
          
                Finally, commit comments definitely should have jokes in them.
                This is actually more critical than wrapping them at 72 characters.
          
            Much more beautiful, is it not?
          • benji-york 3 months ago
            You might like top's commit messages, e.g., https://gitlab.com/procps-ng/procps/-/commit/e6f22569e9db16d...

            commit e6f22569e9db16dbef7d9bdee5bb41b8cb7a03ca

            Author: Jim Warner <james.warner@comcast.net>

            Date: Tue Jul 23 00:00:00 2024 -0500

                top: attempt once again to allow help text translation
                
                Back when our release 4.0.1 was being readied, sources
                were sent to the TP (Translation Project). However one
                person named Benno Schulenberg refused to release them
                for translation. His stated reason was the top command
                line help text which then finally included long forms.
                
                He demanded that the help text be broken into separate
                strings instead of a single large string. But, all the
                top text (some much more complex) has just one string.
                So that stated reason was, at the least, inconsistent.
                
                [ I suspect the real reason was that Mr. Schulenberg ]
                [ thought that the carefully right-justified English ]
                [ wording would also be required of translations too ]
                
                The bottom line was that Benno took it upon himself to
                change the TP motto from "you code, we translate" into
                "first we tell you how to code and then we translate".
                
                Rather than bend a knee to that despot, I disabled the
                text entirely, admittedly denying users a translation.
                Now, with this commit we enable translatable help text
                but with a hint included to ignore the justified text.
                
                Reference)s):
                . Oct, 2022 - finalized translation exclusion
                commit ab05a3785f29cc4b754e17c53bfb3d8ba054563e
                
                Signed-off-by: Jim Warner <james.warner@comcast.net>
          • darknavi 3 months ago
            > Having commits prefixed by "chore:" or "docs(ui):" aren't that useful.

            I don't use those for humans, I use those for tooling, such as semantic-release. The human-readable bits come after that.

            https://semantic-release.gitbook.io/

            • sam_lowry_ 3 months ago
              I always thought we have tags for tooling.
              • windward 3 months ago
                And the rest of the message. And git-notes.

                Reducing the human-readability of the most human-presented part of the commit, to make it easier for the can-do-billions-of-operations-a-second machine, seems backwards.

            • nindalf 3 months ago
              This isn't prose, it's poetry.
              • chrismorgan 3 months ago
                A lot of the best prose is poetry.
            • Hojojo 3 months ago
              I quite like my current system.

              One word naming the topic or area or system that was changed, then colon separated with a very short sentence giving a summary of the changes, then two lines later (if necessary), a bullet point list of the most important/noteworthy changes, then an explanation for why a thing was changed (if any change in the commit warrants it).

              Honestly, I know most people won't go beyond the first line, but I do find the rest of it very helpful for my own work if I have to go through the commits sometime in the future.

              It also helps that most of it is optional and I decide on a case by case basis whether just the first line is sufficient or I need the whole thing.

              I see in the comments people questioning the purpose of a bullet point list, but it actually is helpful. I don't want to have to check the diff for every single commit if I don't have to. It's time consuming. If a commit message can tell me immediately if it touched something I'm interested in, that's a big time and effort and mental bandwidth saver.

              Example:

              auth: Refactored and fixed edge cases

              - Fixed incorrect handling of token groups

              - Added role enum to replace static strings

              • drac89 3 months ago
                Looks beautiful. And the best part is, if you ever need to fill out a PR template with what you did or list the changes, it becomes so much easier. You don’t even have to remember exactly what was changed, it’s all right there in the commit message.
              • rejschaap 3 months ago
                You get some of this for free if you create branches and squash merge them when finished. Without needing to think much about commit message, just a few words per commit is enough. This is good enough for me and I don't need to waste any time thinking about it.

                Example commits of something I worked on a few days back:

                  $ git l feature/character-selection
                
                  c54825f 3 days ago   Robert Schaap   (feature/character-selection) Simplify color picker, fetch current color
                  d512569 3 days ago   Robert Schaap   Fix recolor for female, clean up files
                  6d05ce4 3 days ago   Robert Schaap   Add color picker to change shirt color
                  441180b 3 days ago   Robert Schaap   Show male in editor
                  17045dc 3 days ago   Robert Schaap   Remove old character
                  95772ff 3 days ago   Robert Schaap   Add characters
                
                Then when I squash merged it I ended up with this commit message:

                  $ git show HEAD~1
                
                  commit be50e0d701d565cebdf4f29e0c9d8030a1a8faf7
                  Author: Robert Schaap
                  Date:   Mon Mar 24 21:29:20 2025 +0100
                
                    Character selection (#14)
                
                    * Add characters
                
                    * Remove old character
                
                    * Show male in editor
                
                    * Add color picker to change shirt color
                
                    * Fix recolor for female, clean up files
                
                    * Simplify color picker, fetch current color
                • kqr 3 months ago
                  Granted, I'm not the target audience of your commit messages, but they tell me very little about what happens.

                  > Add characters

                  I can probably tell from the code that that's what's happening. But what requirements drove these particular characters?

                  > Remove old character

                  What makes it old? How would I recognise an old character in the future?

                  > Show male in editor

                  Why did male not show before? Was there a bug or a partially implemented feature?

                  > Fix recolor for female, clean up files

                  What does it mean to "fix recolor"? And even worse, what is "clean up files"? What requirements drove this file cleaning? Why were the files unclean in the first place?

                  etc. Commit messages in the style of "fix X" or "add Y" or "remove Z" or "nondescript action on W" are the bane of my existence. They seem so meaningful but they don't tell me anything when I'm trying to trace why a particular bug was introduced – or whether it's even a bug in the first place.

                  • Cthulhu_ 3 months ago
                    Yeah I think the most important thing to think about when writing a commit message is the intent; a LOT of people use it as a "work log", describing what they did like "removing a character" or "add color picker".

                    But a commit message needs to describe what the commit does, when applied. A good rule of thumb - also explained on the git site [0] - is to put it in a template like "When applied, this patch will <your commit message>".

                    The grandparent comment is almost there though, using the right tense of "fix" instead of "fixed", the latter being in the work log form of "I fixed such and such".

                    [0] https://git-scm.com/docs/SubmittingPatches/2.2.3#:~:text=Des...

                    • ahofmann 3 months ago
                      Yes! Please tell me _why_ the commit happened. The _what_ is in the diff, so almost no need to tell me in the commit message. Often I get commits with some LLM-generated slop in the commit message. It always looks good and always tells nothing. Commit messages like that are garbage.
                  • nloomans 3 months ago
                    These example commits seem like pretty bad commit messages to me. They are just a summery of the changes (something a motivated reader can rediscover by reading the diff), while leaving out the why, which will be lost to history if not documented.
                    • retSava 3 months ago
                      Yes, the why is very very important, but imo it's also useful with a one-liner summary of the actual change.

                      Consider a trivial change but affecting tens of places in the code, eg an API change. It's very useful to be able to quickly glance past "use new abc-API; required since dependency X bumped to Y" and mentally move on, rather than actually having eyes scanning over those actual changes.

                    • gherkinnn 3 months ago
                      A dev culture that produces nothing but wip and fix bug commits (frequently adding unrelated refactors) will continue to produce noise but prefixed with chore(code): fix bug. I fail to see the benefit behind this and conventional commits.

                      I do not understand why people insist on trowing inane technical solutions at social problems. It doesn't work.

                      • addisonbeck 3 months ago
                        `chore(code): fix bug` doesn't follow conventional commits, so it's not at great example for this point.

                        In my experience conventional commits tend to lower character counts and improve the readability of messages. `bug(auth): adjust XYZ` is shorter than `fix auth bug by adjusting XYZ`.

                      • agnishom 3 months ago
                        Similar to https://www.conventionalcommits.org/en/v1.0.0/ right?

                        I wouldn't say its a lost art... we do this at our company

                        • matsemann 3 months ago
                          What about Gitmoji? [0] Didn't get much love when discussed here[1] but fun concept. At least it makes you think about the commit message, which is better than not. And each commit having one selected emoji forces you to make one commit per improvement, so you can't bundle stuff together.

                          [0]: https://www.bekk.christmas/post/2019/11/gitmoji-yay-or-nay [1]: https://news.ycombinator.com/item?id=21760021

                          • rollcat 3 months ago
                            Depends. Sometimes a one-liner or a reference to a ticket is enough.

                            There are times when I make a one-line change and write a paragraph or two explaining why it had to be done. But these kinds of things often drown in the noise of a dozen other changes. If that one was important enough, I will reference it in an ongoing discussion or documentation, or at least include "read below:" on the first line.

                            I usually see people include a more elaborate commentary with the pull request. If the changeset is good but the series of individual commits is a bit messy, just merge by squashing.

                            (Also: this comment is meta.)

                            • Cthulhu_ 3 months ago
                              A one-liner: sure. A ticket? No; ticket systems are transient and not always available. You shouldn't need to open an external system that may no longer exist in 20 years time (for example) to get the full context.

                              Compare the Linux commit history, every commit has its full context and explanation and they do not rely on external systems.

                              • yaris 3 months ago
                                Our ticket system survived almost 20 years and is useless anyway, because approximately half of the history consists of pairs like: commit 12345 ”fixed a bug, see ticket 54321” - ticket 54321 ”fixed by commit 12345”.
                                • dirkf 3 months ago
                                  20? Try 5...

                                  I"m working on a repository that uses at least four different jira ticket number formats. All commits should have a jira reference but I think only the current format can still be looked up. And maybe the predecessor if you know what jira field to query. All the rest are lost in corporate limbo. Not that those tickets added much more context to the actual commit...

                                  So yeah, always write your commit messages as standalone as possible.

                                  • drac89 3 months ago
                                    I agree maybe not adding the ticket link is better if you know that the system might not be available in the future.

                                    You can not avoid it all the time but maybe It's better to use the PR description for that purpose.

                                    • 3 months ago
                                    • pydry 3 months ago
                                      If I feel the need to write a paragraph in a commit message it's usually a sign that Im writing prose that belongs in actual docs.

                                      Commit messages are a great place to bury docs nobody will look at.

                                    • HelloNurse 3 months ago
                                      The quality of commit messages depends on context. The author seems focused on bringing order to long freestyle messages, presumably for the purpose of accreting a rich but readable history log in long-lived branches, but not all commit messages are like that.

                                      For example, when typical commits are about solving or implementing some support ticket, issue, new feature etc. that is documented elsewhere correct references are far more important than classification of the commit type or descriptive details; special commits (refactoring, chore, docs etc.) are easily noticeable because they don't reference a specific issue and many details are better omitted for the sake of deduplication.

                                        fix(ui): correct alignment on dashboard widgets
                                        
                                        - adjust CSS flex properties
                                        - test on multiple screen sizes
                                        
                                        Fixes #204
                                      
                                      could be (on one line, easier to read in a massive log, and without redundantly describing the problem with misaligned widgets)

                                        #204 - adjusted CSS flex properties of dashboard widgets; tested on multiple screen sizes
                                      
                                      or maybe, depending on what is expected to be explained in issue #204 or not, more technically precise:

                                        #204 - same CSS flex properties for all dashboard widget DIV elements; tested on 800*600, 1880*960 and 2900\*1600 browser windows but not on the standard smartphone emulators
                                      • RustyRussell 3 months ago
                                        I don't care, as long as a commit which fixes a crash, compiler error or test failure quotes the errorv. This helps searching for issues, and also helps later if you find they mis-diagnosed the problem.

                                        Other peeve: quote the core of the bug report you're closing, so when GitHub inevitably goes away/turns evil/starts charging, you don't lose half your knowledge. The git tree should always stand alone.

                                        • stared 3 months ago
                                          I second the Angular-style git commit message convention (https://github.com/angular/angular/blob/main/contributing-do...). Though, it is also art that I have lost.

                                          On a lighter note, I recommend "8 Types of Commit Messages That Show He's NOT the Man for You" https://web.archive.org/web/20210606005031/https://www.codem...

                                          • occz 3 months ago
                                            I'm not sure I'm entirely on board with this particular format, but I do agree with the larger point of well-crafted commit messages - and commits, for that matter - being an important quality feature in a project.

                                            I'd posit that well-structured commits are principally for the benefit of the reviewer of the code. Order your commits in a fashion that makes sense narratively, and give them meaningful commit messages. Use interactive rebasing liberally if need be to accomplish this goal.

                                            As a reviewer, you are well within your rights to decline a PR that consists of a single non-meaningful commit message and a +/- 1000 lines diff. Effort is expected from both parties in checking in code.

                                            • drac89 3 months ago
                                              And the best part is, if you ever need to fill out a PR template with what you did or list the changes, it becomes so much easier. You don’t even have to remember exactly what was changed, it’s all right there in the commit message.
                                            • otikik 3 months ago
                                              This is one of the cases where I think AI can help.

                                              Two usecases I can think of: non-native English speakers and ADHD developers. For those groups, having some tool that autofills the first draft of the commit message (that you can then modify) would probably improve their overall commit message quality.

                                              A quick google gave me several projects:

                                              - https://github.com/Nutlope/aicommits

                                              - https://github.com/insulineru/ai-commit

                                              I'm sure there's more.

                                              • Zopieux 3 months ago
                                                $workplace tried this and it is utter garbage (so far) even with full access to the diff & context.

                                                Just as you'd expect from an LLM, it hallucinates a description that overfits the average commit message. It doesn't make a good summary of what changed, and most importantly (though I don't expect it to) why it changed, which is what I need in a commit message.

                                              • meander_water 3 months ago
                                                This focuses on the format of the git message, but I would argue what matters more is the content.

                                                The most important thing to convey in a git commit message is the why, not the what or how.

                                                The title should be a short summary of the change (the what), so that it can easily be searched for.

                                                The description should explain why this change needed to be made. The how and the what can be determined by reading the code. But more often than not, explaining the why helps to clarify intent so that future readers can determine if your rationale still holds.

                                                • charcircuit 3 months ago
                                                  >while pushing changes that could rival a novel in length

                                                  How is distilling a novel down to a short description and 2 points any better? This format is too limiting.

                                                  • fiskfiskfisk 3 months ago
                                                    And please include the why.

                                                    From the article: "- adjust timeout settings to prevent crashes". Include the details of why the timeout setting lead to crashes; what were the inputs and the cases that caused this.

                                                    This lets us decide whether the fix stays or goes the next time there is an issue in the same piece of code, or your commit broke something unrelated - the person fixing it needs to know _why_ you changed the code.

                                                    • vim-guru 3 months ago
                                                      I prefer: <short description> <BLANK LINE> <Detailed information> <BLANK LINE> <footer>

                                                      Using a type is to contrived, because your commit will often include e.g documentation and a feature. Splitting them for the sake of following this pattern makes no sense.

                                                      • chippiewill 3 months ago
                                                        You can actually specify multiple types in one go usually.

                                                        The actual purpose is mostly for tooling to help generate release notes.

                                                      • Phenix88be 3 months ago
                                                        I rarely read the commit messages. It's often faster to just read the code than an obscure description, I'd rather have a small sentence that summarizes what the diff is doing than a technical paper explaining every change in the commit. I don't read pass the title.
                                                        • Cthulhu_ 3 months ago
                                                          Sure, but in bigger projects there's going to be thousands of commits and hundreds of thousands of lines in a diff; reading code becomes infeasible then.

                                                          But it's the only way if there's no commit message discipline, and even if there is it'll be difficult.

                                                          • IshKebab 3 months ago
                                                            Most of the time that's fine, but then you'll find a bit of code that's broken and the change that added it makes no sense and the commit message is empty. Kind of infuriating.
                                                          • twooster 3 months ago
                                                            I'd also consider that this will become increasingly important in the age of LLMs. Want Cursor to one-shot a change? Dollars to donuts the agents of the future will perform a lot better with well-reasoned, well-documented commits to use as reference.

                                                            On the other hand, job security?

                                                            • lima 3 months ago
                                                              One of the best things about Gerrit - besides stacking and turn-by-turn review - is how it emphasizes good commit messages by making them part of the process.

                                                              Each commit becomes one "unit of review", and the commit message can be reviewed just like the code changes.

                                                              • damnitbuilds 3 months ago
                                                                Do people really gain as much time from being able to read these long messages as they lose in writing them?

                                                                I don't think my team would.

                                                                Did the author measure this ? If not, he's the monkey.

                                                                • chrismorgan 3 months ago
                                                                  > Commit messages are the narrative of your project's history. They help others (and your future self) understand why changes were made, making collaboration smoother and debugging less of a nightmare.

                                                                  Yes. And yet:

                                                                  > - Keep each point brief and focused.

                                                                  > - Use bullets (-) and avoid lengthy explanations.

                                                                  No, they lost me there. You often can’t tell the necessary narrative in a single sentence, and you frequently can’t explain why changes were made briefly, and I strongly refute that “avoiding lengthy explanations” should be a goal in commit messages.

                                                                  I exceed ten lines very frequently, and when working professionally I’ve tended to exceed fifty lines at least twice a year. Coworkers have commented favourably on my commit messages, as unusually useful, and some have even lengthened theirs more often after experiencing them.

                                                                  I don’t know what my record is, but it was more than 300, though that was as part of a long-lived refactoring branch that I was needing to rebase every week or two for six months as I continued working on it, migrating from an in-house concatenation-and-#ifdef module builder to ECMAScript Modules, and I was maintaining the dozens of commits meticulously, some regenerated automatically and some requiring manual effort, and so I was detailing the semantics of the changes across a large number of files, so it might not count quite so much. But I’ve done over a hundred a few times for other reasons. Keep your mind open, and look at the longest commit messages in popular repositories, and you’ll find there’s a lot of scope for very long commit messages.

                                                                  —⁂—

                                                                  I loathe Conventional Commits. It saps the art out of the commit message, the tags are frequently badly applicable, the benefits are negligible to negative (changelogs shouldn’t be generated from commit logs—they should be their own thing), and they’re simply ugly.

                                                                  • BrandoElFollito 3 months ago
                                                                    I found that for my home-grade development the commit messages generated by copilot are very good.
                                                                    • pizzly 3 months ago
                                                                      Isn't everyone just putting all the changes in code automatically to an LLM of your choice to create a git commit message already?
                                                                      • ziofill 3 months ago
                                                                        Wow, thanks for this page, I can almost take it as-is and create a Cursor rule for writing commit messages ^^’
                                                                        • khaki54 3 months ago
                                                                          There is someone out there who doesn't let LLM touch his code but uses it solely for commit messages.
                                                                          • Cthulhu_ 3 months ago
                                                                            nit: the author proposes "short descriptions" like "fix null pointer exception in payment module" and "refactor data processing pipeline", however "fix" and "refactor" are already in the "type" part of the commit message. Possibly, "payment module" and "data processing pipeline" can (should?) be extracted from the "scope" element. The characters left over after the type and scope can be used smarter.
                                                                            • tobyhinloopen 3 months ago
                                                                              --message "wip"

                                                                              Why do we care about commit messages? I only read them when rebasing.

                                                                              • naavis 3 months ago
                                                                                They are incredibly helpful when you are trying to find where a bug was introduced, and trying to figure out why some piece of code is the way it is.
                                                                                • tobyhinloopen 3 months ago
                                                                                  If you can’t figure it out based on the git blame and git diff, the code is incredibly unreadable. A comment in the code, or simply writing better readable code seems like a better investment.

                                                                                  Besides, a few passes refactoring and your git history is ruined. No way you’ll find the original commit within any reasonable time frame.

                                                                                  If I move the code to another function, your original commit message will be hard to trace. If the code was commented, the comment would have been moved along. If the code was readable, you don’t need the comment or the commit message.

                                                                                  • naavis 3 months ago
                                                                                    I can only speak from my own experiences, but I have found commit messages extremely helpful, when they explain the "why" of the change. And as unfortunate as it is, many of us also have to work with unreadable codebases.
                                                                                • drac89 3 months ago
                                                                                  It's useful in case like if you ever need to fill out a PR template with what you did or list the changes, it becomes so much easier. You don’t even have to remember exactly what was changed it’s all right there in the commit message.

                                                                                  With structured comments, you can even use the AI to fill out the PR template easily and precisely.

                                                                                • comrade1234 3 months ago
                                                                                  “WIP”