Git: How to skip hooks

Skippity skippity skip!

Git hooks are useful for enforcing standards in your repositories. But sometimes, they’re in the way and you gotta skip ’em (locally), such as when writing “WIP” commits, experiments, and even testing hooks. Here are a few techniques for skipping hooks.

Skip most hooks with --no-verify

Git lets you bypass most hooks with a --no-verify option on triggering commands. For example, you can use commit --no-verify to skip the pre-commit hook:

$ git commit --no-verify -m "hack da prototype"

Uniquely among such commands, git commit supports -n as a short option for --no-verify, so you can shorten the above:

$ git commit -nm "double hack da prototype"

The documentation for each hook covers its skippability with --no-verify. Here’s a complete table covering each command that supports --no-verify and which hooks it skips:

CommandHooksNotes
commitcommit-msg, pre-commit-n short option
mergepre-merge, commit-msg 
rebasepre-rebase 
pullpre-merge, commit-msgHooks only apply if merging
pushpre-push 
ampre-applypatch, applypatch-msgNiche “apply mailbox” command. Added in this commit, pending release in 2.40.0.
p4 submitp4-pre-submit, p4-prepare-changelist, p4-changelistNiche Perforce integration command.

Skip a hook partially with an environment variable

It’s common to use a hook manager that installs itself as one or more Git hooks, and then runs several tools within each hook. My favourite of these is the pre-commit framework.

Most hook managers have a way of skipping only some of the tools they run. Git doesn’t allow extra command options to be passed to hooks, but it will pass environment variables through to the hook. Thus, most hook managers accept an environment variable to skip tools.

The pre-commit framework lets you skip tools with the SKIP environment variable. You set it to the list of tool ID’s to skip, separated by commas (docs):

$ SKIP=check-added-large-files,check-copyright git commit -m "Add Pirates of the Carribean 4k"

For other hook managers, read their friendly docs.

Skip “unskippable” hooks with core.hooksPath

Here’s a hack for skipping hooks without a corresponding --no-verify option. Git loads hooks from your repository’s .git/hooks directory by default, but you can change this with the core.hooksPath. The trick is to modify this option for a single command with -c:

$ git -c core.hooksPath=/dev/null switch main

The special empty file /dev/null prevents Git from finding any hooks, so it will continue as if none exist.

If you need to disable hooks for a while, you could save this option in your repository’s configuration file:

$ git config core.hooksPath /dev/null

Revert later with:

$ git config --unset core.hooksPath

Just don’t forget!

Hopefully you don’t need to use this override habitually, but it can be useful occasionally for testing hooks.

Fin

Aye aye skipper,

—Adam


Learn more about pre-commit, particularly for Python projects, in my DX book.


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: ,