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):

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

https://gist.github.com/arturadib/97a17752301ee796f9a0

https://medium.com/@ripoche.b/using-global-pre-commit-hook-to-prevent-committing-unwanted-code-edbbf957ad12

https://man7.org/linux/man-pages/man1/grep.1.html