Перехватчик Mercurial не работает должным образом

Это должно быть очень просто запустить, но по какой-то причине это не будет работать с моим репозиторием Mercurial. Все, что я хочу, это чтобы удаленное репо автоматически запускало hg update всякий раз, когда кто-то нажимает на него. Итак, у меня есть это в моем файле .hg/hgrc:

[hook]
changegroup = hg update

Просто, верно? Но по какой-то причине это никогда не выполняется. Я также попытался написать сценарий оболочки, который сделал это. .hg/hgrc выглядел так:

[hooks]
changegroup = /home/marc/bin/hg-update

и hg-update выглядело так:

#!/bin/sh
hg help >> /home/marc/works.txt;
hg update >> /home/marc/works.txt;
exit 0;

Но опять же, это не обновляется. Содержимое hg help записывается в works.txt, но ничего не записывается в hg update. Есть ли что-то очевидное, что мне здесь не хватает? Это мучает меня уже несколько дней, и я просто не могу заставить его работать.

Обновить

Хорошо, еще раз, использование переключателя -v в командной строке с моей рабочей станции, отправляющей в удаленное репо, не печатает никаких подробных сообщений, даже если у меня есть эти echo строк в .hg/hgrc. Однако, когда я делаю push из клона репо в той же файловой системе (я вошел в систему через SSH), я получаю следующее:

bash-3.00$ hg -v push ../test-repo/
pushing to ../test-repo/
searching for changes
1 changesets found
running hook prechangegroup: echo "Remote repo is at `hg tip -q`"
echo "Remote repo wdir is at `hg parents -q`"
Remote repo is at 821:1f2656753c98
Remote repo wdir is at 821:1f2656753c98
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
running hook changegroup: echo "Updating.... `hg update -v`"
echo "Remote repo is at `hg tip -q`"
echo "Remote repo wdir is at `hg parents -q`"
Updating.... resolving manifests
getting license.txt
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Remote repo is at 822:389a6c7276c6
Remote repo wdir is at 822:389a6c7276c6

Так что это работает, но опять же только тогда, когда я нажимаю из той же файловой системы. Это не сработает, если я попытаюсь нажать на репозиторий с другой рабочей станции по сети.


person Marc W    schedule 11.05.2009    source источник
comment
У меня точно такая же проблема. Вы уже нашли решение?   -  person smf68    schedule 30.01.2010
comment
Никогда не находил решения для этого. Я давно сдался.   -  person Marc W    schedule 31.01.2010


Ответы (9)


Я провел некоторое время, исследуя это сам. Я думаю, что ответ на проблему описан кратко здесь:

Вывод должен быть перенаправлен на stderr (или /dev/null), потому что stdout используется для потока данных.

По сути, вы не перенаправляете на стандартный вывод и, следовательно, не загрязняете стандартный вывод.

person Barry    schedule 03.09.2010
comment
Вау, я рад, что они наконец включили это в FAQ! Хотел бы я иметь это год назад. Спасибо, что наконец ответили на вопрос. знак равно - person Marc W; 04.09.2010
comment
Ну наконец то? История вики показывает, что это было в FAQ по крайней мере с января 2008 года: mercurial .selenic.com/wiki/FAQ/ - person Ry4an Brase; 08.11.2010
comment
Святая корова... Не могу поверить своим глазам... Что за программный дизайн... =/ - person vines; 25.10.2012

Что ж, пройдя те же этапы разочарования, что и Марк В. некоторое время назад, я, наконец, нашел решение проблемы, по крайней мере, когда удаленное обслуживание выполняется с помощью WSGI-скрипта hgwebdir.

Я обнаружил, что при использовании такого рода удаленной отправки через HTTP или HTTPS Mercurial просто игнорирует все, что вы записываете в файл .hg/hgrc или в свой репозиторий. Однако ввод хука в конфигурацию hgwebdir делает свое дело.

Так что, если нижняя строка вашего скрипта hgwebdir.wsgi выглядит примерно так:

application = hgwebdir('hgweb.config')

раздел конфигурации [hooks] должен войти в упомянутый hgweb.config.

Одним из недостатков является то, что эти хуки выполняются для каждого репозитория, указанного в разделе [paths] этой конфигурации. Несмотря на то, что HG предлагает другую функцию с поддержкой WSGI (hgweb вместо hgwebdir) для обслуживания только одного репозитория, похоже, что он не поддерживает никаких ловушек (и не имеет никакой конфигурации). Однако это можно обойти, используя hgwebdir, как описано выше, и используя некоторые Apache RewriteRule, отображающие все в нужный подкаталог. Этот работает для меня:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/reponame
RewriteRule ^(.*)$ reponame/$2 [QSA]

Получайте удовольствие, используя удаленные перехватчики через HTTP: D

person smf68    schedule 02.02.2010
comment
Это странное поведение, но у меня та же проблема, и перемещение раздела ловушек в файл hgwe.confog исправило ее. - person Dasha Salo; 12.03.2010
comment
hgweb теперь точно так же поддерживает файл конфигурации. - person Colin Fine; 23.11.2010
comment
Вы только что сэкономили мне пару часов. Спасибо - person Lmwangi; 17.03.2011
comment
Ну, это действительно старо, но у меня была та же проблема, и hgrc теперь работает на основе репо, по крайней мере, в mercurial 2.6... помните, что hgrc должен принадлежать www-data - person JorgeeFG; 27.11.2013
comment
Для меня это была очень и очень полезная информация. Спасибо! - person LarsVegas; 04.09.2015

Прежде всего, я хочу исправить несколько комментариев выше.

  • Хуки вызываются также при проталкивании через файловую систему.
  • Нет необходимости хранить хук в репо, на котором вы хотите, чтобы они работали. Вы также можете написать тот же хук, что и в вашем вопросе, на стороне пользователя. Вы должны изменить событие с группы изменений на исходящие, а также указать URL-адрес удаленного репо с ключом -R. Затем, если отправляющий пользователь имеет достаточные привилегии в удаленном репо, хук будет выполнен успешно.

.hg/hgrc

[hooks]
outgoing = hg update -R $HG_URL

Теперь о вашей проблеме... Я предлагаю создать перехватчики как prechangegroup, так и changegroup и напечатать отладочный вывод.

.hg/hgrc

[hooks]
prechangegroup = echo "Remote repo is at `hg tip -q`"
                 echo "Remote repo wdir is at `hg parents -q`"
changegroup    = echo "Updating.... `hg update -v`"
                 echo "Remote repo is at `hg tip -q`"
                 echo "Remote repo wdir is at `hg parents -q`"

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

person Aamir    schedule 17.05.2009
comment
Благодарю за ваш ответ! Попробую в понедельник и сообщу. - person Marc W; 17.05.2009
comment
Что интересно, то, что вы мне дали, работает, когда это локальный толчок, но не работает, когда это удаленный толчок. Я даже только что использовал changegroup = hg update в одиночку, и это то же самое; работает для локального, а не для удаленного. Что еще более странно, так это то, что я не думаю, что это работало на прошлой неделе, когда я пробовал это. Что-то должно быть другим. Есть ли какая-то конфигурация, которую мне нужно установить, чтобы разрешить запуск хуков во время удаленных толчков? - person Marc W; 18.05.2009
comment
Не могли бы вы объяснить немного больше, что именно вы подразумеваете под локальным нажатием и удаленным нажатием? Я снова прошу вас опубликовать вывод отладки, когда вы нажимаете удаленно с ключом -v. Используйте крючки, которые я предоставил. Я понятия не имею, есть ли какая-либо конфигурация для выполнения хука. Вы должны проверить свои файлы ~/.hgrc и /etc/hgrc на предмет нестандартной, подозрительной конфигурации. — Аамир 4 секунды назад [удалить этот комментарий] - person Aamir; 19.05.2009
comment
Под локальным толчком я подразумеваю отправку из той же файловой системы (без доступа к сети). Поэтому я клонировал репозиторий в другое место в своем домашнем каталоге и вернул его обратно в исходное репо. Под удаленной отправкой я подразумеваю отправку с другой рабочей станции по сети. Когда я нажимаю удаленно с помощью -v, я фактически не получаю отладочный вывод. Только при локальном нажатии что-либо печатается, и это именно то, что вы ожидаете (tip и wdir находятся на разных оборотах до обновления и такие же после). Я могу опубликовать его позже, если вы все еще хотите его. - person Marc W; 19.05.2009
comment
Я разместил то, что вы просили в моем вопросе, Аамир. - person Marc W; 20.05.2009
comment
Эта награда заканчивается через час, и я хотел бы отдать ее вам, но я не получил от вас ответа, и это все еще не работает... - person Marc W; 20.05.2009
comment
Таким образом, это определенно проблема с удаленной отправкой, потому что вы сказали, что локальная передача через файловую систему сработала, как и ожидалось. Я не использовал mercurial в сетевой среде, поэтому не имею права решать эту конкретную проблему. Но я предлагаю вам внимательно просмотреть файлы hgrc и найти что-то подозрительное. Также глава 10 hg-book является авторитетным объяснением mercurial hooks. Дайте ему обезжирить. - person Aamir; 20.05.2009
comment
Всю последнюю неделю я практически жил по этой главе книги, пытаясь в ней разобраться. Он очень подробный, но не содержит много информации об устранении неполадок или отладке, кроме встроенного крючка ACL. - person Marc W; 20.05.2009

Моя проблема заключалась в том, что мое приложение hgwebdir работало как пользователь «hg», но репозиторий принадлежал мне, поэтому мне пришлось добавить этот бит конфигурации в hgweb.config, чтобы заставить его запускать хуки:

[trusted]
users = me
person flowblok    schedule 14.08.2011

Он должен находиться в удаленном репозитории hgrc. Звучит так, как будто это в вашем локальном репо.

Изменить: это также зависит от того, как вы нажимаете. Некоторые методы не вызывают хуки с правой стороны. (подходит ssh, я думаю, что HTTP, а файловая система нет)

Edit2: Что, если вы нажмете «локально» на компьютере удаленного репо. У вас могут быть разные пользователи/разрешения между веб-сервером и файлом hgrc. (См. [сервер] и доверенные директивы для hgrc.)

person Macke    schedule 11.05.2009
comment
На самом деле он находится в удаленном репо .hg/hgrc. Кроме того, все нажатия происходят через https. - person Marc W; 12.05.2009
comment
В порядке. Можете ли вы нажать на ssh и посмотреть, получите ли вы другой результат? - person Macke; 14.05.2009
comment
Хорошо, я только что попытался нажать локально, используя пользователя, которому принадлежит репозиторий. До сих пор нет кости. У меня тоже ошибок нет. Кажется, что он просто игнорирует команду обновления hg. - person Marc W; 14.05.2009
comment
Очень странно. Вы пытались использовать хук Python вместо команды оболочки? - person Macke; 15.05.2009

У меня была такая же проблема с отправкой из Windows Eclipse через http, но после захвата stderr я обнаружил, что нужен полный путь к файлу hg.bat. Мой раздел хуков теперь выглядит так:

[hooks]
incoming = c:\Python27\Scripts\hg.bat update > hg_log.txt 2>>hg_err.txt

Надеюсь, это поможет кому-то другому. СтивТ

person SteveT    schedule 19.10.2010

Попробуйте включить отладку ловушек, чтобы посмотреть, почему он не работает.

Вероятно, проблема с правами доступа или что-то в этом роде.

person John Weldon    schedule 11.05.2009
comment
Я тоже так пробовал. Ничего полезного не сообщили. Никаких ошибок, предупреждений или чего-то в этом роде. - person Marc W; 11.05.2009

заняло некоторое время, но я получил его работу.

я начал с

[hooks]
tag=set >&2
commit=set >&2

>&2 направляет его в стандартную ошибку, чтобы удаленные консоли отображали его.

при удалении это должно выводиться в консоль, если оно запущено

hg push https://host/hg   -v

Это не так.

Я использовал hgweb.cgi, поэтому без разницы переключился на hgweb.wsgi.

я обнаружил, что некоторые хуки не вызываются на удаленном компьютере.

когда я переключил его на

[hooks]
incoming= set >&2

тег хуков и фиксация, похоже, не вызываются, но вызываются входящие и набор изменений. Я не подтверждал других.

теперь, когда я заработал, я вернулся к hgweb.cgi, и все работает так же.

person Pete Brumm    schedule 08.11.2010

Причина, которую я нашел для этого, не имеет ничего общего с перенаправлением stdout на stderr. Как вы можете видеть на вики-странице, это не указано в текущей версии вики https://www.mercurial-scm.org/wiki/FAQ#FAQ.2FCommonProblems.Any_way_to_.27hg_push.27_and_have_an_automatic_.27hg_update.27_on_the_remote_server.3F

Проблема, которую я обнаружил, связана с разрешениями.

В моей первоначальной настройке у меня был пользователь, скажем, hguser с репозиторием на своем доме, и скрипт /etc/init.d/hg.init для запуска hg serve. Проблема заключалась в том, что hg serve запускался root, в то время как большинство файлов в репозитории относились к hguser (некоторые из них в какой-то момент переключились на root, но это не будет возражать, так как я исправлю их с помощью chown)

Решение:

  • chown -R hguser:hguser /home/hguser/repo (чтобы исправить ВСЕ файлы, вернуться к hguser)
  • запускаем su hguser -c "hg serve ..." (в моем случае с /etc/init.d/hg.init)
  • changegroup = hg update -C моложе [hooks] в repo/.hg/hgrc как обычно

Теперь он должен работать на push

PS: в моем случае я предпочитаю обновляться до главы определенной ветки, поэтому я использую hg update -C -r staging, чтобы промежуточный сервер обновлялся только до главы предполагаемой ветки, даже если tip из другой ветки (например, development )

Кстати, мой сценарий hg.init закончился так: (обратите внимание на часть su hguser)

#!/bin/sh
#
# Startup script for mercurial server.
#
# @see http://jf.blogs.teximus.com/2011/01/running-mercurial-hg-serve-on-linux.html

HG=/usr/bin/hg
CONF=/etc/mercurial/hgweb.config
# Path to PID file of running mercurial process.
PID_FILE=/etc/mercurial/hg.pid

state=$1

case "$state" in
'start')
    echo "Mecurial Server service starting."
    (su hguser -c "${HG} serve -d --webdir-conf ${CONF} -p 8000 --pid-file ${PID_FILE}")
  ;;

'stop')
  if [ -f "${PID_FILE}" ]; then
    PID=`cat "${PID_FILE}"`
    if [ "${PID}" -gt 1 ]; then
      kill -TERM ${PID}
      echo "Stopping the Mercurial service PID=${PID}."
    else
      echo Bad PID for Mercurial -- \"${PID}\"
    fi
  else

    echo No PID file recorded for mercurial
  fi
  ;;

*)
  echo "$0 {start|stop}"
  exit 1
  ;;
esac

PS: должно быть указано на http://jf.blogs.teximus.com/2011/01/running-mercurial-hg-serve-on-linux.html

person arhak    schedule 29.05.2015