фатальный: эта операция должна выполняться в рабочем дереве на обработчике предварительного получения

В процессе предварительного получения, я получаю исключение fatal: This operation must be run in a work tree при попадании на хук pre-receive. Я уверен, что крючок попался, потому что я могу напечатать свое собственное сообщение с помощью этого крючка.

#!/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

Является ли мой код ловушки неправильным или какой-либо другой проблемой? но этот хук работает отлично .


person Parkavi    schedule 09.10.2017    source источник
comment
может быть связано: stackoverflow.com/questions/25638767 /git-diff-on-a-bare-repo   -  person Nahuel Fouilleul    schedule 09.10.2017


Ответы (2)


HEAD (если он вообще существует) не будет указывать на то, что вы ожидаете в голом репозитории (он указывает на начальное значение для HEAD, когда кто-то запускает git clone).

Из хука перед получением вы должны прочитать список хэшей коммитов из STDIN, чтобы узнать, на какой коммит вам следует обратить внимание:

от git help githooks :

предварительно получить

...

Этот хук выполняется один раз для операции получения. Он не принимает аргументов, но для каждой обновляемой ссылки получает на стандартный ввод строку вида:

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

где <old-value> — старое имя объекта, хранящееся в ссылке, <new-value> — новое имя объекта, которое будет храниться в ссылке, а <ref-name> — полное имя ссылки. При создании новой ссылки <old-value> равно 40 0.

Итак, ваш скрипт может сделать что-то вроде:

#/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
person LeGEC    schedule 09.10.2017
comment
Также обратите внимание, что хук pre-receive будет получать всевозможные изменения, поэтому вы можете проверить, находится ли $refname в refs/heads, а не говорить, что новый тег помещается в /refs/tags. - person Mort; 10.10.2017

git diff имеет две формы:

  • с одной фиксацией разницы между рабочим деревом относительно ‹commit>
  • с двумя коммитами diff между двумя коммитами

потому что на голом репо нет рабочего дерева, попробуйте использовать

git diff --name-only --diff-filter=d HEAD~1 HEAD
person Nahuel Fouilleul    schedule 09.10.2017
comment
Действительно, чтобы исправить скрипт, необходимо проверить правильный заголовок, однако причиной ошибки действительно было использование git diff только с одним коммитом. - person Nahuel Fouilleul; 10.10.2017