Skip to content

Instantly share code, notes, and snippets.

@xezrunner
Last active April 15, 2026 18:40
Show Gist options
  • Select an option

  • Save xezrunner/e6dbafcc21fcbc976c93bdee0f371a08 to your computer and use it in GitHub Desktop.

Select an option

Save xezrunner/e6dbafcc21fcbc976c93bdee0f371a08 to your computer and use it in GitHub Desktop.
nocheckin pre-commit hook for Git
#!/bin/sh
# Author: xezrunner (github.com/xezrunner)
# Inspired by Jonathan Blow's nocheckin setup with SVN (twitch.tv/j_blow) (youtube.com/@jblow888)
# Credits to DustinGadal on r/Jai: reddit.com/r/Jai/comments/jp0vjy/nocheckin_behavior_in_gitsourcetree/gbfhzd1
# gist.github.com/xezrunner/e6dbafcc21fcbc976c93bdee0f371a08
# This pre-commit hook checks for the keyword "$NOCHECKIN_KEYWORD" in staged files,then aborts the commit
# if any matches were found, with output of file path, line number and match preview.
# To install, copy and rename to <repo>/.git/hooks/pre-commit (merge contents if already exists)
# The file name has to be "pre-commit" for Git to use it. It is also compatible with git GUIs.
# On Unix, mark the file as executable with `chmod +x .git/hooks/pre-commit`.
keyword=${NOCHECKIN_KEYWORD:-nocheckin}
# Use color only when stderr is attached to a real terminal and supports colors:
set_grep_color() {
if [ -t 2 ] && [ -z "${NO_COLOR:-}" ] && [ "${TERM:-}" != "dumb" ]; then
grep_color=always
else
grep_color=never
fi
}
git_grep() {
git \
-c color.grep.filename=normal \
-c color.grep.linenumber=normal \
-c color.grep.separator=normal \
grep --cached --color="$grep_color" -n -I -F -e "$keyword" -- "$1"
}
find_matches() {
git diff --cached --name-only --diff-filter=ACMR |
while IFS= read -r path; do
git_grep "$path" || : # '|| :' = Continue on error
done
}
# Search for nocheckins:
set_grep_color
matches=$(find_matches)
# Nothing found, continue:
[ -n "$matches" ] || exit 0
# nocheckin(s) found, block:
printf 'Commit blocked due to "%s" in staged files:\n\n' "$keyword" >&2
printf '%s\n' "$matches" >&2
printf '\nRemove these markers, or commit with --no-verify to bypass.\n' >&2
exit 1

nocheckin pre-commit hook for Git

This Git pre-commit hook checks for a keyword ("nocheckin" by default) in staged source files and blocks the commit if any matches are found, with the output of file path, line number and match preview.

It's is inspired by Jonathan Blow's nocheckin setup with SVN, as seen on his programming sessions at Twitch and YouTube.
Additional credit to DustinGadal on the r/Jai subreddit for original implementation.

Tested on Linux (GNOME OS 50), macOS Sequoia and Windows 11 (with Git for Windows) + GitHub Desktop on each.

Installation

As a download:

  1. Download the file from above, either by clicking Download ZIP and extracting it, or by clicking Raw and saving the contents to a file.
  2. Copy and rename the file to <repo>/.git/hooks/pre-commit. If you already have a pre-commit hook, merge it into the file.
  3. On Unix systems, you will likely need to mark the file as executable by running chmod +x ./git/hooks/pre-commit. Git will warn about this when issuing a commit if it's the case, though it will perform that commit without running this hook.

⚠️ NOTE: The file name has to be "pre-commit" for Git to recognize and use it as a pre-commit hook.

Manually:

  1. Copy the contents of the file from above.
  2. Create <repo>/.git/hooks/pre-commit and paste the contents, or merge if you have your own.

Usage

CLI:

  1. Stage files with git add <file> ...
  2. Attempt making a commit with git commit ...
  3. Observe the commit failing when at least one of the staged files contains a nocheckin.

GUI (Github Desktop)

  1. Mark files for staging.
  2. Attempt making a commit.
  3. Observe the commit failing when at least one of the staged files contains a nocheckin.

Changing the keyword

You can change the keyword that's used for rejecting commits by setting the NOCHECKIN_KEYWORD environment variable, or editing the default at the top of the script (default_keyword=nocheckin)

Screenshots

Command-line example:

GitHub Desktop GUI example:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment