Git Plumbing

tl;dr learn you a git

In the previous post, I was using git show to get a list of files modified by a commit. As I was cleaning up open browser tabs, I noticed an interesting sidebar in the DuckDuckGo search results: a Stack Overflow answer relating to exactly what I was trying to do.1 The punchline is that I should probably have been using git diff-tree instead. I changed the code, but the thing that stuck with me is the mention of plumbing versus porcelain:

Preferred Way (because it’s a plumbing command; meant to be programmatic) … Another Way (less preferred for scripts, because it’s a porcelain command; meant to be user-facing)…

I’ve been aware of the distinction git makes between plumbing and porcelain. git show is meant to be used by a human. It’s formatted nicely, and color helps highlight relevant sections. Meanwhile, I don’t ever recall using git diff-tree in my nigh-daily use of git, and its brutalist aesthetic means I’m unlikely to anytime soon.

While building the git hook, I had to figure out how to get rid of the human-friendly stuff, specifically the commit message. The solution felt a bit hacky: using an empty --format= option to suppress the commit message. git diff-tree is clearly biased towards a much starker look at the data. There’s a similar --no-commit-id option, but there’s no custom formatting to fiddle with, merely a flag to set or un-set; and an ID is generally much more machine-useful than a message.

The plumbing-and-porcelain dual is a useful concept. It’s an example of good API design, where higher layers are build on lower, more fundamental layers. A couple closing thoughts:

First, there’s a very similar phenomenon to test-driven development at play here. In both cases, it pays to be sensitive to any friction being experiencing. Friction generally indicates going against the grain in some way, that perhaps there’s a smoother path to the goal.

Second, Unix’s everything-is-text philosophy goes a long way toward reducing the pain felt by that friction. After all, git show and git diff-tree are both displaying text, just in slightly different ways, and I can use the same set of tools to munge it.

Hopefully the next time I find myself into a situation like this, I will learn to dig a little deeper into the plumbing of whatever tool I’m using.

  1. Incidentally, it was very cool to see that inline with my search results. I think I initially ignored it ’cause I figured it was an ad or something. Return

Tools Used

git
2.23.0