мой post-receive, git hook, с двумя командами не работает

У меня есть три репозитория git:

  1. голый репозиторий на моем сервере git
  2. локальный репозиторий (A) на моем ноутбуке (я разрабатываю веб-страницы на этом компьютере).
  3. локальный репозиторий (B) на хостинг-сервере (я использую его как http-сервер).

Я установил post-receive, крючок на стороне сервера, в голом репозитории, чтобы репозиторий (B) вытягивался из голого, и чтобы сервер git отправлял уведомление по электронной почте, когда я фиксирую и нажимаю из репозитория (A) в голый репозиторий. Файл после получения, который я сделал в голом репозитории, выглядит следующим образом:

#!/bin/sh
ssh -l MYUSER -i PRIVKEY www.HOSTINGSERVER.com "cd GITDIRECTORY;git pull"
. $(dirname $0)/post-receive-email

И я также установил переменные окружения в голом репозитории:

git config hooks.mailinglist "MyMailAddress"
git config hooks.announcelist "MyMailAddress"
git config hooks.emailprefix "FooBar"
echo FooBar > description

Я ожидал, что репозиторий (B) будет извлечен, и сервер git отправит электронное письмо с уведомлением по электронной почте после получения, когда я зафиксирую и отправлю в голый репозиторий, но пост-получение не сработало, как я надеялся. У него был репозиторий (B), но сервер git не отправлял электронную почту. Я не видел ошибок электронной почты в журналах на сервере git.

Когда я закомментировал ssh-часть пост-получения, я получил электронное письмо. Когда я закомментировал часть после получения электронной почты, репозиторий (B) вытащил правильно. Когда и часть ssh, и часть после получения электронной почты активны, пост-получение имеет только извлечение из репозитория (B) и не отправляет никаких электронных писем.

Я не знаю, почему пост-получение не работает, как я ожидаю, когда и часть ssh, и часть пост-получения электронной почты существуют одновременно.

Любой намек и комментарий приветствуются. Заранее спасибо.


person Taiki Bessho    schedule 23.12.2017    source источник


Ответы (1)


TL;DR: ssh -n.

Фоновые факты:

  1. Хук post-receive получает ввод на свой стандартный ввод. При чтении стандартного ввода вы получите одну строку для каждой обновленной ссылки в форме, описанной в документация по гитхукам.

  2. Все хуки Git, которые получают ввод на стандартный ввод, делают это через канал. (Я утверждаю, что это плохая идея — они должны получать свои входные данные в виде файлового дескриптора, открытого во временном файле, — но это отдельная битва. Даже если бы это было не так, вам все равно понадобится еще один трюк.)

  3. Чтение ввода, доступного в канале, потребляет этот ввод. Как только оно прочитано, оно исчезло.

    (Кстати, именно поэтому read, встроенный в оболочки, настолько неэффективен: необходимо читать ввод по одному байту за раз, так что только read собирается прочитать потребляется.)

Имея это в виду, рассмотрите команду ssh и этот отрывок из ее документации:

-n     Перенаправляет стандартный ввод из /dev/null (фактически запрещает чтение из стандартного ввода).

Итак, что произойдет, если вы запустите ssh без -n? Конечно, он будет читать стандартный ввод. Но... сколько много он будет читать? Ну, строго говоря, это зависит от: ssh запускает несколько процессов и/или потоков, и есть гонка, если есть много ввода stdin и команда, запущенная на удаленном конце, выполняется очень быстро, но в целом количество, которое ssh читает все стандартного ввода.

Теперь сверьтесь с фоновым фактом № 3 и ответьте на вопрос: что осталось на стандартном вводе после завершения работы ssh?

Теперь подумайте о том, что делает ваш хук после получения, который отправляет электронную почту. Он обязательно должен прочитать свой стандартный ввод, чтобы увидеть, какие ссылки были обновлены. Какие данные он получит на свой стандартный ввод?

Если вы запретите ssh читать (и тем самым потреблять) все входные данные, хук post-receive сможет читать (и потреблять, но теперь это уже не имеет значения) все входные данные и, следовательно, функционировать правильно.

person torek    schedule 23.12.2017
comment
МОЙ БОГ! ssh -n решил мою проблему! Благодаря вашему объяснению я также понял, что фон имеет значение. Я потратил около половины дня на эту проблему. Огромное спасибо! - person Taiki Bessho; 23.12.2017