[HN Gopher] How to Write a Great Git Commit Message (2014) ___________________________________________________________________ How to Write a Great Git Commit Message (2014) Author : baristaGeek Score : 36 points Date : 2022-04-26 21:35 UTC (1 hours ago) (HTM) web link (cbea.ms) (TXT) w3m dump (cbea.ms) | ufo wrote: | I hate that rule about 50 characters. IIRC, it started because | someone noticed that the _average_ commit message in the linux | kernel is about 50 characters. Then, for whatever reason it | morphed into this widely propagated mantra saying that the | _maximum_ should be 50 characters. | slaymaker1907 wrote: | Writing a good commit message within those constraints is kind | of like writing a haiku. It's kind of entertaining sometimes, | though I think it should be a suggestion rather than a rule. | mwt wrote: | This is from 2014, but I guess not much has changed since then. | tsuujin wrote: | This has been my commit bible for years. I feel like it has been | battle tested and has made my life easier. | carlosdp wrote: | I prefer Github's method of "git commit messages don't matter, | pull requests do". | | Nowadays, you can easily enforce that the ultimate commit log | looks rather nice by doing this: | | 1. Make it so the only merge strategy allowed on a repo is | "Squash and Merge", so each PR = 1 commit in main branch | | 2. Have engineers care about the pull request quality rather than | commit messages | | It's easier to be more expressive in a pull request, and | intermediate changes while working on a PR aren't super | interesting to me. | elpakal wrote: | If you really want just one commit on your PR you can reset | your branch to its target before you merge: | | git reset --soft <target> | | Which will undo all commits and leave all modified files in the | staging area. Then you can make one commit and force push it to | replace your branch @ remote. | xorcist wrote: | Or just git rebase -i like normal people. | fbormann wrote: | Thanks for the tip, man! Really helpful indeed. | bern4444 wrote: | You could also rebase and squash all commits into a single | one and then rewrite the commit message with git commit | --amend. | rubyist5eva wrote: | this works until you want to leave Github for whatever reason | ericmcer wrote: | Why? Wouldnt the commit history contain only the one squashed | commit and its legible message? | lelandfe wrote: | This happens sometimes when private repos change hands. I've | worked at places where we've been given zips of git repos - | commit messages reference PR and issue #'s from long distant | organizations. | | I've since started policing PRs whose commit messages | reference things inside of our GitHub. At least provide a | summary of what you're linking, for the worst case future. | mwt wrote: | This works well enough if (and only if) your company has a | culture of small, atomic PRs. | munk-a wrote: | Not really, I recently merged in a two commit branch where | one commit was me changing all the vendor configuration for | the framework we were using to a new version and the other | was all the changes needed to support the change. That PR | affected thousands of files in total but the need to | frequently rebase the branch to avoid killer merge conflicts | encouraged a low commit count. rebase -i can be your friend | if you've got a long branch history that adds essentially no | value (i.e. "Tried this thing/Didn't work reverting/Tried | this other thing/Still no dice/Switching workstations"). | | An arbitrarily large number of file changes can be packed | into a single commit, sometimes for review purposes it makes | sense to purposefully isolate different groups of changes in | a manner that doesn't mesh with how the dev work was actually | done - sometimes I just don't want to have an ugly commit | history. I'm allowed to be OCD about my work and sweep the | commit where I added print __LINE_NUM__ between each LOC to | track down a bug one time that I was too lazy to use gdb | under the rug. | eikenberry wrote: | But the PRs aren't part of your git repository? IMO a git | repository should be self contained and not require a hosted | provide to give context. It lets you manage your work with | superior local tooling and without a browser running. Basically | I take the exact opposite approach where my PRs are always just | a short summary of the commit messages and provides a place for | me to put the github specific things like the "Fixes #..". But | I make sure my commits are a clean artifact of the changeset by | themselves (ie. I do any squashing, etc, on them outside of the | PR). | mwt wrote: | GitHub (by default) uses the name of the PR as the merge | commit message and also includes the commit message of each | commit in the log. Having whitespace-altering "Dummy commit | to trigger CI, ugh!" commits in a git history isn't good but | it still clutters the `git log` with stock squash+merge | GitHub use. | | I can't speak for everybody, but if GitHub goes down | completely and I only had access to my git logs, I'd struggle | to recreate ~20% of the information scattered across issues | and PRs. This issue is external to merging preferences, but | it's definitely not solved by squash-merges and descriptive | merge messages. | shagie wrote: | > Having whitespace-altering "Dummy commit to trigger CI, | ugh!" | | `git commit --allow-empty` may be sufficient for that | "there is a new commit" trigger in many cases. If so, that | may be preferable to whitespace changes as those clutter up | the blame. | | As an aside, my initial commit on a repo is an empty one so | that I can branch from a completely empty repo to do | radical rewrites and yet maintain a history relationship | with that initial empty commit (which I feel is preferable | to an orphan branch and then a merge with unrelated | histories ... though those tell slightly different stories | in the log). | mwt wrote: | Yep, `--allow-empty` is my preferred solution. It's | unfortunately not up to me how other people choose to do | this | stormbrew wrote: | > As an aside, my initial commit on a repo is an empty | one so that I can branch from a completely empty repo to | do radical rewrites and yet maintain a history | relationship with that initial empty commit (which I feel | is preferable to an orphan branch and then a merge with | unrelated histories ... though those tell slightly | different stories in the log). | | Oh cool, I thought I was literally the only person on the | planet to do this lol. I'd do it for branchpoints too | except git rebase by default acts very poorly with empty | commits in the edited history (deletes them). I wish this | was normalized (ie. there was a flag to `git init` to add | a commit message for a root commit). | stormbrew wrote: | > Having whitespace-altering "Dummy commit to trigger CI, | ugh!" commits in a git history isn't good but it still | clutters the `git log` with stock squash+merge GitHub use. | | The frustrating thing about this is that this "omg minor | commits on a merged branch clutter up the log!" is entirely | a UI problem created by github's naive view of history | where it shows things in a bafflingly obtuse linear order | instead of letting you do something like `--first-parent` | like the command line client lets you do. | | Git itself has more than enough tools to give you that | 'squashed' view without actually squashing anything, github | just has no interest in providing it to you for whatever | reason. | | Also yes to the sibling comment that if you want to make | something happen with a commit use `--allow-empty` and not | "bump number" or "add random whitespace". Please. | slaymaker1907 wrote: | It would also help if people were better about keeping a | clean commit history for PRs. Ideally, a new commit | should only get pushed to a branch per change relevant | for reviewers. If the CI is causing the error, people | should work on a temporary branch and resolve it there | first before cherry picking things over into the PR | branch (after rebasing the intermediate commits on the | temp branch). | | Rebasing is a really nice tool, though I think the UI is | really lacking. A simple GUI for interactive rebasing | would help a lot. Most clients I've used (which isn't a | ton since I generally prefer the CLI) don't even have an | option for rebasing at all. | mwt wrote: | > github's naive view of history where it shows things in | a bafflingly obtuse linear | | This hits home, it pretty much describes how I visualize | logs in my head (compared to the visualizations I see | that are more 2-D, branching off and merging together, | etc.). I have a hard time working with some of the more | advanced features because of this, and it'll probably | always be an uphill battle to shift my thinking from | linear to not-so-linear ... | Everlag wrote: | That's such a different approach than I've grown used to, but | different platforms encourage different flows. | | I've been using bitbucket (not the shiny nice new bitbucket) at | work for years and its PR search is so abysmally bad that | anything in the PR message but not in the commit message may as | well not exist once its merged. `git log` is forever, bitbucket | search is /dev/null | | I'm curious what other affordances or lack of affordances | encourage what git behavior. | simonsaysso wrote: | For the code review step, sure, commit messages don't really | matter unless your team reviews PRs commit-by-commit. | | How many times do you actually change the default squashed | message? If you write a series of garbage commit messages, I | don't particularly trust that you'll write a very good squashed | message, either. How many times do people skip updating the PR | description with new information or features from comments? If | your commit messages are good, the auto-squash message will be | good and one will have a network dependency on GitHub to figure | out what decisions went into that change. | | In general I agree with your goal of a great commit log: 1 PR = | 1 commit in the main branch. But I feel like GitHub is just the | wrong tool to use if you want that. I used to use Gerrit, where | commit messages _are_ your PR description. Sure, it makes you | interact with git in some unfortunate ways, but the tradeoff is | enforced commit cleanliness. | transitivebs wrote: | 95% of the commits on my personal open source projects use emoji | commit messages. https://github.com/transitive-bullshit/commit- | emoji | | PRs matter a lot more than commit messages, especially if you're | squashing + merging / rebasing. | sph wrote: | But why? That's even more useless than just describing a commit | in a couple words. | | I'd rather see a commit saying "fix bug" when bisecting or | reading a commit history than ":heart:" | [deleted] | themanmaran wrote: | For those who write multi paragraph commit bodys, is there a tool | you use to format them? | | Example commit on the React repo [1]. It just seems like a lot to | type in the command line. | | [1] | https://github.com/facebook/react/commit/ec52a5698e2dfea7050... | jrib wrote: | My vim will automatically wrap when I am typing a git commit | message. | | Should be set by default from here: | https://github.com/vim/vim/blob/2f0936cb9a2eb026acac03e6a8fd... | imron wrote: | vi :set tw=70 | a_t48 wrote: | There's a good chance this was made in Github's squash+merge | dialog. | | Edit: never mind, it's auto wrapped at some number | knoebber wrote: | Emacs + magit and auto-fill-mode | xorcist wrote: | Command line? git normally opens your chosen editor and you are | free to write away to your heart's content. | | I guess you could stuff multiple -m in there and git will | format it nicely, but the editor is for writing and is best | used for that. | rubyist5eva wrote: | > It just seems like a lot to type in the command line. | | I spend my entire workday day in Vim. | pvg wrote: | Previously | | https://news.ycombinator.com/item?id=13889155 2017, 118 comments | | https://news.ycombinator.com/item?id=10212582 2015, 90 comments | bern4444 wrote: | I like the conventional commit style [0]. You may have seen these | in open source repos or used them at work. They look like | | feat: support new line chart | | fix: update props for new line chart | | chore: bump dependency version | | What's also cool is there are tools (semantic release) that will | then handle automatically the versioning and publishing of your | module based on these commits using the commit type (feat, fix, | chore etc) to determine the next appropriate version [1]. | | [0]https://www.conventionalcommits.org/en/v1.0.0/ | | [1]https://github.com/semantic-release/semantic-release | _virtu wrote: | I built a full pipeline around this. Basically allowed for a | paved road for devs to automatically semantically version and | deploy application and module artifacts for npm with semantic | release by spinning up a repo with some boilerplate generators | I made available to the team. | | Since then I've been obsessed with the conventional commit | format everywhere for my own projects. Even if the commits | aren't parsed for versioning, it just gets you into the habit | of thinking about the scope of the commits. | | The laughable part about building that full paved road pipeline | is that the biggest friction point was always when devs didn't | use semantic commits. At the time when I implemented it I | didn't have checks for the commit format at the pr phase. I DID | have a commitizen cli option as well but that was "Too much | friction". Oh boy did I get bit. As someone who was working on | DX I was constantly surprised by how many questions I got about | something as seemingly simple as the conventional commit format | from a crowd of enginerds. ___________________________________________________________________ (page generated 2022-04-26 23:00 UTC)