Call a Git Hook on Demand

Git hooks are scripts that run at key moments in the version-control lifecycle. And, they’re just scripts! So we can call them when we want. <shell> <hook> For me in this project (Zsh + Husky), this could look like: zsh .husky/pre-commit This runs my pre-commit script anytime.

September 4, 2026

Git Apply Diff

One of my favorite Git tricks is shoveling changes to a Git diff and then applying them later. I’ll be in the middle of a tricky feature, spike, or bugfix, and need to switch gears. So, I redirect my unstaged changes to a diff: git diff > fantastic-feature.diff My global .gitignore ignores *.diff. Later, when I want those changes, I can usually run: git apply fantastic-feature.diff The home directory of my project sometimes contains a dozen or more of these little diffs; things I tried or want to do someday. ...

February 27, 2026

Things I Check Before Opening a PR

What is a programmer but a series of PRs (pull requests)? I optimize PRs to introduce the best code I can, be easy to review, and document my work so I can make sense of it in the future. Here are some things I always check before opening a PR. Passing Static Analyses All of the static analysis tools in my project must pass locally. On a JavaScript project, that’s an auto-formatter (Prettier), linter (ESLint), and type-checker (TypeScript). All of these run on files I touch automatically. If that’s not feasible for you, a Husky pre-commit hook will do the job. ...

February 7, 2026

Git Porcelain and Plumbing 🚽

Git has two kinds of commands: “porcelain” and “plumbing”. I’ve known these terms for a long time, but recently learned I was misusing them. It stops now! “Porcelain” commands are meant for end users to call. git-log, git-show, and git-bisect are a few. “Plumbing” commands are meant for scripts to call and are considered more stable. Commands you’ve likely never heard of like git-update-ref and git-write-tree are plumbing commands. See man git for more info.

January 26, 2026

Timestamped Branch

Git prevents branches with the same name. But sometimes, I want to re-use a name! Here’s my workaround. Context: I use Bitbucket to generate branch names. It will give me a branch for a feature “User logs in” named feature/user-logs-in. That name helps me convey what a branch’s intentions are. But what happens if I open another branch for that feature? Do I have pick a new name, just because Git says so? Not really. ...

November 20, 2025

Why Keep Binaries Out of Version Control

“Keep binaries out of version control” is a truth I’ve always held, but I recently learned more about why. Yes, you don’t want large files in version control, which binaries often are. Yes, you shouldn’t version changes you can’t review, which binary changes are. But even worse, binaries can make your Git repo explode in size over time. Even when your “remove” (quotes intentional) or replace them with new ones, they are part of the repo. They’re cloned every time the repo is cloned, slowing down the developer experience, and even potentially eating up all the allowed space on the repo host. ...

November 20, 2025

"Don't Stay Stuck" Digital Guide Launch

I’m proud to announce the launch of my digital guide to software debugging, Don’t Stay Stuck: A Debugging Guide for Rising Engineers! I’ve been working on this guide on nights and weekends, and it’s the distillation of a decade of debugging triumph and tragedy. Product Pitch Have you ever been stuck on a tough bug and felt you had no path forward? You’ve tried everything you can imagine, and nothing is working? And then: a sharp engineer drops into the session, asks a few questions, and fixes the bug almost immediately! What is this superpower? ...

August 12, 2025

Git Apply a Commit in Reverse

Sometimes I’ll be looking at a Git commit online, and want to put my dev environment in a world where the commit is un-applied. This can be achieved by applying it in reverse. git show <sha> | git apply -R Same behavior as git revert, but without the revert commit.

July 30, 2025

Show How A File Is Ignored In Git

Today I solved a mystery: a file was being Git-ignored in a new project that didn’t have a .gitignore. Here’s me learning this by trying and failing to add it: $ git add destroy.sh The following paths are ignored by one of your .gitignore files: destroy.sh This output tells me some .gitignore is telling Git to ignore my script. Another way to confirm this is the check-ignore command: $ git check-ignore destroy.sh destroy.sh The output here is the match; a file named destroy.sh is indeed being ignored. But how? We can answer that question with the -v flag: ...

May 31, 2024

Apply a Patch in Reverse

Need to undo a code change? You could revert. Or, you could apply the patch without creating a commit. That’s what I want to do much of the time. Use git apply with the -R (reverse) flag: git show 8cc13b1 | git apply -R All the changes from 8cc13b1 get applied to your working directory. In a large commit, do this tactically by limiting to just one file or directory. git show 8cc13b1 src/fileToRevert.ts | git apply -R

March 24, 2023