2

I'm planning to set up a client side git hook to force a commit to fail if any file in the commit contains the text "donotcommit".

Is it possible to hook the execution of "git add", such that I can run a shell script at the time files are added, and permit or deny the add based on the exit status of the shell script.

1

1 Answer 1

2

Unfortunately, there is not. However, there is a workaround.

Git lets you filter files before staging (and before checkout), if needed. You can hook right there. See the filter section in the docs

For example, lets say, all .txt files may not contain the word donotcommit. First, we create the filter in .git/config or in your global config file:

[filter "donotcommit"]
    clean = bash -c 'tee >(cat) | grep donotcommit -qi && exit 1 || exit 0'
    smudge = cat
    required

The clean filter is run on add, the smudge filter on checkout. required tells git that whenever this command fails, the file is in a bad state and can not be added. The command receives the file-contents piped to stdin, and since it's a filter and what it outputs gets added as file-content, we need to make sure to pass the whole file through, thats what the tee >(cat) in clean and the cat in smudge is for. The | grep donotcommit -q && exit 1 || exit 0 part should be clear: Look for donotcommit (case insensitive), if found, exit with an error (1), otherwise exit cleanly (0).

Then, register this filter for txt-files in the repositories .gitattributes file

*.txt filter=donotcommit

Result:

C:\dev\test>echo Hello World > test.txt

C:\dev\test>git add test.txt

C:\dev\test>echo Hello World [DONOTCOMMIT] > test.txt

C:\dev\test>git add test.txt
error: external filter 'bash -c 'tee >(cat) | grep donotcommit -qi && exit 1 || exit 0'' failed 1
error: external filter 'bash -c 'tee >(cat) | grep donotcommit -qi && exit 1 || exit 0'' failed
fatal: test.txt: clean filter 'donotcommit' failed

C:\dev\test>
2
  • Regretfully, while this works, it's a little overzealous. Not only is the filter run when doing a git add but also when doing a git status. That causes problems if any currently unstaged file has the donotcommit trigger string in it.
    – dgnuff
    Oct 28, 2017 at 1:05
  • Doesn't seem to run on git status for me, at least I don't see a error message
    – tkausl
    Oct 28, 2017 at 1:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.