2

In the process of pre-receive, I get the fatal: This operation must be run in a work tree exception while hit the pre-receive hook. I am sure the hook is hitting, Becasue I can print my own message by that hook.

#!/usr/bin/env bash

FILES=`git diff --name-only --diff-filter=d HEAD~1`
for COMMIT in $FILES;
  do
      case $COMMIT in
      *.txt|*.pdf|*.docx)
        echo "Hello there! We have restricted committing that filetype.
        exit 1
        ;;
      esac
done
exit 0

Whether my hook code is wrong or any other issue? but this hook is running perfecly.

smarber
  • 4,829
  • 7
  • 37
  • 78
Parkavi
  • 35
  • 6

2 Answers2

4

HEAD (if it exists at all) will not point at what you expect in a bare repository (it points at the initial value for HEAD when someone runs a git clone).

From a pre-receive hook, you have to read the list of commit hashes from STDIN to know what commit you should look at :

from git help githooks :

pre-receive

...

This hook executes once for the receive operation. It takes no arguments, but for each ref to be updated it receives on standard input a line of the format:

<old-value> SP <new-value> SP <ref-name> LF

where <old-value> is the old object name stored in the ref, <new-value> is the new object name to be stored in the ref and <ref-name> is the full name of the ref. When creating a new ref, <old-value> is 40 0.

So your script could do something like :

#/usr/bin/env bash

# read lines from stdin, assign first value to 'old', second to 'new',
#   third to 'refname' :
while read old new refname; do

  # use $old $new and $refname inside this block
  FILES=`git diff --name-only --diff-filter=d $old $new`

  ...
done
LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • Also note that the pre-receive hook will get all sorts of changes, so you may want to check to see if `$refname` is in `refs/heads` as opposed to say a new tag being pushed to `/refs/tags` – Mort Oct 10 '17 at 00:01
-1

git diff has two forms:

  • with one commit diff between working tree relative to the <commit>
  • with two commit diff between two commits

because on a bare repo there is no working tree, try to use

git diff --name-only --diff-filter=d HEAD~1 HEAD
Nahuel Fouilleul
  • 18,726
  • 2
  • 31
  • 36
  • Indeed to fix the script this needs to review correct head, however the cause of error was really the use of git diff with only one commit – Nahuel Fouilleul Oct 10 '17 at 14:11