Legible Git History

As a software engineer, think of everything you produce as something that gets consumed.  If you make it easier to consume, it will cause less friction for others as well as yourself.  This applies to code, documentation, UX, variable names, URL routes and even something as innocuous as our commit messages for our code.

Making your history legible will pay off if you ever have to investigate why something is done.  Or if your teammate needs to know why you may have done something.


Commit history can be messy depending on how you work.  For me, I produce a lot of commits like this:

commit c3328b81b2734dce59755b47b4b215356e97d253 (users)
Author: Dave Dash <dd@dd.com>
Date:   Tue Oct 29 16:50:18 2019 -0700

    wip

commit 7db58241e566ae4bacda622009e03a2cfe0f62a6
Author: Dave Dash <dd@dd.com>
Date:   Tue Oct 29 16:15:43 2019 -0700

    wip

commit e45f3faaafcd470f2f894599637a2ccbaf2e92c7
Author: Dave Dash <dd@dd.com>
Date:   Wed Oct 23 21:22:33 2019 -0700

    wip

commit 7308fe901b72e7bec857d3e8841e31f4872f63ee
Author: Dave Dash <dd@dd.com>
Date:   Wed Oct 23 21:22:27 2019 -0700

    wip

commit dcf5f0823218530e111b6f057c0fc64da454c179
Author: Dave Dash <dd@dd.com>
Date:   Wed Oct 23 20:28:40 2019 -0700

    wip

commit b668a8884e1e799113d0e27af48da6aa95147e81
Author: Dave Dash <dd@dd.com>
Date:   Wed Oct 23 19:30:15 2019 -0700

Where wip is my shorthand for Work In Progress.  In fact, I have an zsh alias that commits everything when I type wip.  I do this periodically so I don't loose my code, and then I go back in and rebase everything later.

My usual workflow is to make a bunch of "messy" commits.  They are purely checkpoints so I can rollback if necessary, but nothing that I knowingly would export to Github for a pull request, and certainly not to my main branch which might roll into production.

Other commit messages that I've seen are code review feedback or cleanup or even something more substantive like new controller.  While they explain what you are doing, they often don't explain what is being done to the code or why.  If anyone needs to figure out what was happening, they'd only be able to guess if they looked at the code changes.

A better example of a decent commit message, might be something like this:

commit 429ffc4b55d9f39625dc5931001b386719effa7e (HEAD -> POI, origin/master, master)
Author: Dave Dash <dd@dd.com>
Date:   Tue Mar 10 10:41:58 2020 -0700

	Display facts from database
    
    	This loads facts from the Facts model instead of reading from 
    	yaml files.

This  prescribes exactly what is happening.  It isn't perfect since it doesn't cover the "why", but "why" is really only necessary when things aren't obvious.  Loading data from a database, versus from a file, is pretty standard in web development.  No need to explain why.

The rule of 50 and 72

Formatting the message consistently helps.  The first line of the commit message is the subject. It should be 50 characters or less because anything more is likely to get cut off by other tools, including Github or your git-aware text editor. This also forces us to be short and sweet.

After the first line, leave a blank line, and then followup if necessary with any explanations. We wrap this at 72 characters, because the variety of tools we use don't format this text nicely, nor do they often respect rich text formatting.

When to break these rules?

There are times when you cannot summarize things adequately in 50 characters. It's easy to go beyond 50 characters to describe something and edit it down. This is a writing skill. Overtime brevity will become easier. However, if you spend more than a few minutes word-smithing your commit message, it's fine to make a best effort. A sixty character message, or a paragraph that doesn't wrap correctly will be a mild inconvenience, but that might be a worthy trade-off.  


Let me know your other git commit tricks: commits@davedash.33mail.com.