I've got a new blog post up at Meedan (where I work). It's about longform git commits: what they are and how they can make your life as a software developer easier.

My spiciest git take is you should ban "-m" from your git repertoire and go full verbose invoking a text editor from the CLI to write commits.

Here's the part where I say, "by the way we are hiring a backend engineer with Rails experience and a machine learning engineer" please come work with me and make nice long commit messages:

@darius I can't write a commit any more without using commit -v, it's so good

@BestGirlGrace @darius I'm legitimately a bit confused because I never use -v, I just use `git commit` and the diff pops up in my text editor ready for me to write a nice verbose commit message, as is my wont. Do people routinely change repo or local settings to make `-v` necessary?

@keithzg @darius when you write your commit message without -v, does git put a nice diff summary of the changes below the message?

@BestGirlGrace @darius Ohhh sorry I see, the *full* diff. I suppose variable autocompletion would be nice! I tend to trawl through `git diff` as a step beforehand so seeing the specifics of the diff didn't even occur to me, heh, whoops.
@BestGirlGrace @darius Absolutely do the 2 or 3 tier approach to my commit messages as described here, with the modification that I generally acquiesce to the standard form at my work where we put the bugtracker issue ID at the start of a commit. Unfortunately most of the computer engineers at my work will put *just* that issue ID with maybe some very terse "description", like

> BugID:999 - Commit fix

which means reading back through the commit log *requires* cross referencing our bugtracker.

@darius To answer the eternal question "what on earth were they thinking?"

@darius I'm already a long git commit message writer so this looks like very much my jam!


What I like about this is that it combines good editing practice in multiple layers.

The first line (what you're calling the subject line) of a git commit message really aught to be a simple "<verb> <subject>", but then you're right that there's room for more detail.

I'm still struggling to get some devs to perform good commit messages.

@darius Weird take: I very occasionally use -m with mercurial (I believe single line commit messages are almost never a good idea, but sometimes I do things that are not a good idea) but I NEVER use -m with git because it is completely baffling to me what files do and don't get included on any one git commit and entering the editor is the one surefire way to be CERTAIN you know what it is you're committing...!

@mcc Yeah that is one of the main reasons I avoid -m so that tracks. Cool that mercurial does not share that problem.

@mcc @darius As confusing as the staging phase is for some people, when you do use it fully, then git status and git diff --cached reflect what will land in the commit

@darius I wish I could convince people to quit using `-m`. Whenever I run Git workshops at work, I try to motivate the use of your Git logs as documentation and why you should go ahead and open up a text editor for your commit message.

I don't know that I've ever convinced anyone, though…

@darth_mall Yeah it's why I tried to use my "modal" example there.

Something that I didn't mention in the article is it's a way of documenting like... how MUCH work went into a commit. Sometimes you have a ~1 line commit that took you all day. A verbose commit is where you can really show your team why that took all day (and it is likely to help someone in the future since tiny changes with huge ramifications should be well-documented!)

@darius I don't know if I'm going to do any more Git workshops (it's a lot of work), but if I do, I'm going to include this along with the Chris Beams post about formatting

@darius coworker suggests adding a bit on how to change your default editor! probably a lot of people are scared of being tossed into vi

@catalina I think by default it will actually pull up a little picker that lets you pick between vi, nano, and some other ones but... yeah people should have vscode or whatever as an option too haha

@catalina anyway, updated the post with a hyperlink to a how-to on changing the default. thanks for the prod!

@darius I tend to put those longform descriptions in pull requests, but I see how it could be valuable to have them in the commit message.

When you say ban "-m", surely you mean except for WIP/checkpoint commits that will be rebased/squashed later, right?

@graue yes, correct on -m.

What I like about having this in git is that it stores the important information in git rather than in github dot com

@darius @graue If you require merge commits, the description of the PR gets copied into the merge commit message. It’s another reason why I personally don’t understand the Rebase/Squash lifestyle: use merge commits and that PR description you put a lot of writing in on github gets nicely copied into your git history.

(Plus then you can use tools like —first-parent with merge commits.)

@darius I'm not a happy person when I'm doing git archeology and come across commit messages just saying "updated" or "fixed bug". Especially if something changed in the code that broke something else and I want to know the implications of changing it back, or further. Information in issue tracking systems tends to get lost, or may be inaccessible over time, or untraceable. (I don't even want to include issue numbers in commit messages, though they are great in merge requests).

I also dislike git -a though...

Now I want to see that programming language that doesn't support multiplication...

@gidi I also dislike -a, I also avoid `git pull` and `git push` without remote/branch identifiers but I don't want to overwhelm people heheh

@gidi and yes, I like keeping as much info in git itself as possible because that way even if you switch issue trackers or git hosting services you still have a very useful history

@darius very much enjoyed that, and learned about -v which is going to save me keystrokes and focus in the future!

@darius such a great write up. I didn't even know that was possible. Thank you :bunneaww:

@darius You probably know this, but you can set commit.verbose true in your config and never have to remember -v again! This is also really useful because you get it mid-interactive-rebase, when it’s a little harder to pass -v manually.

@darius ooh I didn't know about `--grep` with `-i`, I needed that like… 20 minutes ago

@darius I'm still laughing at providing multiplication by dividing by the inverse of the operand ...

@yojimbo thank you I'm very glad at least one person found that as funny as I did 😂

@darius I generally agree, but I have a caveat to add there

When you feel the urge to write a lot in the commit message, a part of it should probably go into a comment in the code instead, so that the reasoning behind a piece of code is directly accessible there

Description why/how something *is* -> code comment
Why something was changed -> commit message

@DrMcCoy I've found myself moving away from verbose comments in projects where commits are verbose - the understanding becomes that every line of code has rich metadata you can inspect via git blame etc. Still not sure where I land on the correct distribution of information.

@darius I see the git history as something that might not always be available. For example, when generating a classic tarball with automake's make dist, the .git directory is usually stripped off

I run Gentoo on my personal machines. I more than once had to investigate why a package suddenly broke compilation on an update (especially when I have set an uncommon set of USE flags). I usually have to dive into the code there and that's usually from a release tarball without git repo

@darius In a corporate context, when working on something as part of a subcontract, when the full code is part the contract, the repository might not be. And in fact the contractee might not have any use for it and wants just a ZIP of the code instead. At least in my neck of the woods, the wider automotive industry in Germany, that's more common than you'd think

@darius I agree, but I'm also a stickler for the standard formatting in a git commit.

The first line should be an overview, and be 50 characters or less.

Put as much information as you want in the body, but keep it at the right line limit. I believe it's 72 for the body.

@darius @DrMcCoy
It's probably untrve or sth as it's not CLI, but I really like git gui for committing. I can easily review my commit while writing the commit message, and unstaging that debug printf() that slipped in is just as easy, without having to abort the committing/writing commit message process.

And yes, commit message that contain actual information are super helpful and everybody should write them that way instead of "Fixed #123", referencing some bugtracker that might be gone next year

I also consider the ticket number absolutely essential and our subject line standard mandates it when applicable (and it should normally be applicable).

The point about punctuation is a good one, and I will ususally commit with a draft message from the CLI and then immediately run git commit --amend to fix it up a bit.

But then I will also most of the time run interactive rebases and fix things up, both code and messages, before pushing things.

I will take this moment to evangelize --rebase-merges which is an absolute godsend and really helps with separating things into focused, topical PR branches.


@clacke @darius

We've got some advocates at my work for putting it in the body instead of the subject line, but I do find it essential to have the ticket number available in the short history.

@lordbowlich @darius Yes. If I'm about to deploy to prod, I want to be able to see at a glance in my git lg* which features will be included in the deploy and we will put ticket numbers in the release notes too, and in the subject of mails discussing aspects of a feature, etc.

* basically a git log --graph --decorate --oneline but with a little bit more candy, see…

@darius I'm a big fan of magit, which leads you towards good commit hygiene and also shows the whole diff at commit time, but `commit -v` is an absolute lifesaver if I'm just on the command line. I've used it like 3 times today already! Thanks for the tips

@darius Great stuff! Magit, the Emacs Git client, actually has verbose commit messages as the default which is one way it encourages good practice, it seems.

@darius Yes. I encourage a #git commmit message body format of "Before, …
Now, …
Issue: CMO-123"

@markstos @darius Sounds quite like the C4 format:
Problem: the thingamjigs smurf too much

Solution: transmogrify the flerps

@clacke @darius Yes, Before/After is more flexible as it doesn’t assume the current status was a problem.

@darius This is why I just don't use the command line. My UI has that second box and it's just begging me to use it....

@fuzzybinary "UI" huh... I'll have to research what that is...

Sign in to participate in the conversation
Friend Camp

Hometown is adapted from Mastodon, a decentralized social network with no ads, no corporate surveillance, and ethical design.