Automatically Prevent (Some) Bad Git Commits
Some bad Git commits you can’t prevent. I’m talking about the ugly, last-minute implementations that pass the test suite but will give you nightmares for days. Or commits with nasty bugs that will only reveal themselves days later on a corner case.
Some bad commits, though, you absolutely can prevent. And there’s a way to automatically prevent them, every time you invoke git commit
: Git hooks.
Git hooks come in two main varieties, client-side and server-side. I’ll only be referring to the client-side hooks here. Basically, a Git hook is a script that is run at any one of several points in the Git workflow. The hook we’ll be examining here is the “pre-commit” hook that fires off just after you execute git commit
. It runs before you’re asked for a commit message or even given the default message.
Bob Gilmore has an excellent collection of these pre-commit hooks. You clone the repo in your home directory, then run setup.sh
followed by the path to the Git repo you’d like to install the hooks into. Once that’s done, every time you commit in that repo, Bob’s script will check every committed file for:
- Pry calls: (
binding.pry
) - Stray Git merge conflict markers: (
>>>>
,<<<<
,====
) - Strings like
PRIVATE KEY
that might mean you’ve accidentally committed your private SSH key. Oops. - Various other logging and debugging calls that you usually don’t want in production code.
I’ve forked the project to add a couple of nasty little buggers that I certainly have never, ever committed, no sir:
- Launchy
save_and_open_page
calls - Ruby debugger calls
If any of these warning signs are detected in the code that’s about to be committed, the script will throw up a warning with the file name(s) and abort the commit. For example:
Error: git pre-commit hook forbids committing lines with "debugger" to spec/features/test_spec.rb
--------------
To commit anyway, use --no-verify
Then, you can either remove the offending code or run git commit --no-verify
to bypass the checks. Pretty great, huh?