Reminder Tokens When Using Git
2023-05-13
EDIT(2024-01-05): Added instructions on how to use Git templates to easily set up the script in new projects.
When working on my one-man projects, I tend to focus on the main goals first to get them working quickly. If I get any ideas for refinement while coding, I’ll just slap a very simple // @TODO consider doing foo
somewhere and move on. (I prepend @ since I could end up with unrelated syllables to and do next to each other.)
Sometimes, however, there are issues I really want to be addressed before committing. Maybe it’s about covering an important edge case or reverting some code tweaks I made for quick debugging. In those cases, I’ll add a comment containing @REM
and, with the magic of Git pre-commit hooks, I’ll be forced to address it dutifully. (REM here stands for reminder. Yes, it could be confused for remove, but it’s short and I know what it means.)
To set up this hook, create a file named pre-commit in the .git/hooks directory with the following content:
#!/bin/bash
# Check that there are no leftover reminder tokens in edited files.
REMINDER_FOUND=0
REMINDER_TOKEN="@REM"
for FILE in $(git diff --cached --name-only --diff-filter=ACM); do
if grep -iFq $REMINDER_TOKEN $FILE; then
echo "Found ${REMINDER_TOKEN} in ${FILE}:"
grep -iFnT $REMINDER_TOKEN $FILE
REMINDER_FOUND=1
fi
done
exit $REMINDER_FOUND
This is a Git hook that, when you run git-commit, will check any files you edited for the presence of the reminder token. If any are found, you’ll see a message like the one below, and the commit will fail.
Found @REM in src/constants.cpp:
10: // @REM Revert to original values before committing.
The check is case-insensitive, so it will also match @Rem
and @rem
.
If, for whatever reason, you want to commit anyway, add -n
or --no-verify
to your git-commit command to bypass all pre-commit hooks.
It’s important to aware that this is a client-side hook and will not be committed to remote repositories. You’ll have to recreate this file if you want your hooks applied in a project you cloned. There are workarounds to this issue, nicely described by others here and here. I’ll summarize the first approach here (but do pay a visit to the two posts):
- enable Git templates:
git config --global init.templatedir '~/.git-templates'
, - create a file with the above contents and save it as ~/.git-templates/hooks/pre-commit,
- make the hook executable:
chmod a+x ~/.git-templates/hooks/pre-commit
, - run
git init
to create new or update existing repos.
Another problem with the hook as I implemented it: if a file you edited already contained @REM
inside it, it will refuse to let you commit. You can use the --no-verify
flag described above. Or you could use a different reminder string to adapt to the codebase you’re working on. Or you could change the condition to git diff --cached -U0 $FILE | grep -iFq $REMINDER_TOKEN
. I haven’t had any problems yet so I haven’t bothered.
Reference
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
https://git-scm.com/docs/githooks
https://git-scm.com/docs/git-commit
https://git-scm.com/docs/git-diff
https://coderwall.com/p/jp7d5q/create-a-global-git-commit-hook