Git пост-приемный крючок не работает

Мы используем git с центральным репо (используя Gitosis). Я создал post-receive hook для генерации сообщения электронной почты в список рассылки dev, когда изменения переносятся на центральное репо, и для создания документации из папки документации в репозитории git.

Следовательно, в ~ git/у меня есть каталог, мы будем называть его 'a', который содержит клон репо git. Крюк post-receive выглядит так:

#!/bin/bash
cd ~git/repositories/a.git
. ~git/post-receive-email &> /dev/null
( cd ~git/a && git pull &> ~git/pull_log.log && php ~git/a/scripts/generate_markdown_documentation.php &> ~git/doc_log.log )

Работает электронная почта script, но генерации документации нет. Содержимое pull_log.log:

fatal: Not a git repository: '.'

Это заставляет меня думать, что он не переходит в правильный каталог в строке 5 выше script. Я ошибаюсь? Как я могу заставить это работать?

Изменить: Я обновил hook после приема, как это было предложено в ответах. Теперь script:

#!/bin/bash
function die {
  echo "$*" >&2; exit 1
}

function checkgit {
  [ -d "$1/.git" ] || die "$1 could not possibly be a git repo; $1/.git is not a dir"
}


cd ~git/repositories/a.git
. ~git/post-receive-email &> /dev/null
( set -x
checkgit ~git/a
cd ~git/a
checkgit .
pwd
git pull
php ~git/a/scripts/generate_markdown_documentation.php )

И я получаю следующий вывод из git push:

+ checkgit /var/git/a
+ '[' -d /var/git/a/.git ']'
+ cd /var/git/a
+ checkgit .
+ '[' -d ./.git ']'
+ pwd
/var/git/a
+ git pull
fatal: Not a git repository: '.'
+ php /var/git/a/scripts/generate_markdown_documentation.php

Чем больше помощи?

О, и если я запустил script сам, он работает (я запускаю его, говоря "hooks/post-receive" )

Обнаружена проблема, благодаря serverfault - в основном, переменные окружения GIT_DIR и GIT_WORK_TREE устанавливаются при запуске hook, и это влияет на git тянуть вниз. Исправление переменных устраняет проблему.

Ответ 1

Вам нужна дополнительная диагностика, например,

function die {
  echo "$*" >&2; exit 1
}

function checkgit {
  [ -d "$1/.git" ] || die "$1 could not possibly be a git repo; $1/.git is not a dir"
}

В этот момент, в подоболочке прямо после скобки, вы можете попробовать что-то вроде

set -x # show exactly what executed (writes to stderr)
checkgit ~git/a
cd ~git/a && checkgit . && git pull ...

Вы также можете рассмотреть перенаправление всего stderr подоболочки, например,

( ... ) 2>/tmp/mydiagnosis$$.log

(Это временная мера и в порядке, только если в журналах нет конфиденциальной информации.)


OK Сайлас, ваша дополнительная информация исключает множество неудобных возможностей. Я приближаюсь к концу моего git fu, но вот еще несколько вещей, которые можно попробовать:

  • Перейдите в ~git/a и посмотрите, можете ли вы сделать его git pull вручную. Это должно завершиться неудачей.
  • Перейдите в ~git/a и запустите git status. Это также должно потерпеть неудачу. Если это не так, то git дает вам очень плохое сообщение об ошибке.

Если оба шага терпят неудачу, ~git/a не является клоном, который, как вы думали, был. Переименуйте его, создайте новый клон и убедитесь, что проблема может сохраняться.

Если первый шаг удастся вручную, то происходит что-то странное, и я сбиваю с толку.

Если первый шаг завершился неудачно, но второй будет успешным, у вас может возникнуть проблема с ветвями:

  • Возможно, у repo ~git/a установлена ​​неправильная ветка, и для вашего репо требуется ветвь, которой она не имеет. Попробуйте git branch -a и посмотрите, что вы видите что-то неожиданное.

  • Возможно, у вас есть ветка, но она не связана с удаленным репозиторием. На этом этапе вы должны погрузиться в ~git/a/.git/config, и я действительно не знаю, как объяснить, что вы ожидаете найти там. В этот момент вам понадобится настоящий эксперт git; Я просто играю по телевизору.

Ответ 2

Недавно я столкнулся с подобной проблемой, и я думаю, что она связана с переменными среды, которые git устанавливает, в частности переменную $GIT_DIR. Если у вас есть этот набор, все команды git в других репозиториях начинают действовать странно. В основном я думаю, что запуск тэга git внутри крюка должен быть вызван в нейтральной среде оболочки, которая не имеет этих нечетных переменных и приводит к путанице git, хотя я еще не понял, как это сделать.

Ответ 3

unset GIT_DIR - это решение, которое работает для фатальной ошибки, которую вы видите.

Это относится ко всем скриптам в перехватах (post-update - еще один общий), который использует команду git внутри него. Команда git использует GIT_DIR из env вместо pwd.

Подробнее см. fooobar.com/info/22926/....