Mercurial フックが正しく実行されない
-
21-08-2019 - |
質問
これは非常に簡単に実行できるはずですが、何らかの理由で私の 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
. 。ただし、同じファイルシステム上のリポジトリのクローンからプッシュを実行すると (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
したがって、それは機能しますが、これも同じファイルシステムからプッシュした場合のみです。ネットワーク経由で別のワークステーションからリポジトリにプッシュしようとしても機能しません。
解決
私はこれについて自分で時間をかけて調べました。問題の答えが簡潔に説明されていると思います ここ:
STDOUTがデータストリームに使用されるため、出力はSTDER(または /dev /null)にリダイレクトする必要があります。
基本的に、stderr にリダイレクトしないため、stdout が汚染されます。
他のヒント
そうですね、少し前に Marc W と同じような挫折のステップを経た後、少なくとも hgwebdir WSGI スクリプトを使用してリモート サービスを実行する場合には、最終的に問題の解決策を見つけました。
HTTP または HTTPS 経由でこの種のリモート プッシュを使用する場合、Mercurial は .hg/hgrc ファイルまたはリポジトリに書き込まれたものをすべて無視することがわかりました。ただし、サビに入ると、 hgwebdir 設定内 効果があります。
したがって、あなたの収益が hgwebdir.wsgi スクリプトは次のようなものです
application = hgwebdir('hgweb.config')
[hooks] config セクションは、前述のセクションに入る必要があります。 hgweb.config.
1 つの欠点は、これらのフックが実行されることです。 すべてのリポジトリ その設定の [paths] セクションにリストされています。HG は単一のリポジトリのみを提供する別の WSGI 対応関数 (hgwebdir の代わりに hgweb) を提供していますが、その関数はフックをサポートしていないようです (構成もありません)。ただし、これは、上で説明したように hgwebdir を使用し、Apache RewriteRule ですべてを目的のサブディレクトリにマップさせることで回避できます。これは私にとってはうまくいきます:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/reponame
RewriteRule ^(.*)$ reponame/$2 [QSA]
HTTP 経由でリモート フックを使って楽しんでください :D
まず最初に、上記のコメントをいくつか修正したいと思います。
- フックは、ファイル システムをプッシュするときにも呼び出されます。
- フックを操作するリポジトリ内にフックを保持する必要はありません。質問と同じフックをユーザー側で作成することもできます。イベントをchangegroupから発信に変更し、-RスイッチでリモートリポジトリのURLを指定する必要があります。その後、プッシュするユーザーがリモート リポジトリに対して十分な権限を持っている場合、フックは正常に実行されます。
.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 スイッチを使用してプッシュすると、どのフックが実行されているかがわかります。それでも理解できない場合は、出力を投稿してください。お手伝いできるかもしれません。
私の問題は、hgwebdir アプリケーションが「hg」ユーザーとして実行されているが、リポジトリが私によって所有されていたため、フックを実行できるようにするには、次の構成を hgweb.config に追加する必要があることでした。
[trusted]
users = me
それを持っている必要があります リモート リポジトリの hgrc。ローカルリポジトリにあるようです。
編集:押し方にもよります。一部のメソッドは右側のフックを呼び出しません。(ssh はそうです、HTTP はそうだと思います、ファイル システムはそうです ない)
編集2:リモート リポジトリのコンピューターで「ローカル」にプッシュするとどうなるでしょうか。Web サーバーと hgrc ファイルの間で異なるユーザー/権限が存在する可能性があります。([server] と hgrc の信頼できるディレクティブを参照してください。)
http 経由で Windows Eclipse からプッシュするときにも同じ問題が発生しましたが、stderr をキャプチャした後、hg.bat ファイルへのフル パスが必要であることがわかりました。私のフックセクションは次のようになります。
[hooks]
incoming = c:\Python27\Scripts\hg.bat update > hg_log.txt 2>>hg_err.txt
これが他の人に役立つことを願っています。スティーブ
試す フックのデバッグをオンにする 実行されない理由を確認します。
おそらく権限の問題か、そのような問題です。
しばらく時間がかかりましたが、うまくいきました。
私はから始めました
[hooks]
tag=set >&2
commit=set >&2
>&2 はそれを標準エラーにパイプして、リモート コンソールに表示します。
リモートの場合、実行中の場合はコンソールに出力されるはずです
hg push https://host/hg -v
そうではありませんでした。
hgweb.cgi を使用していたので、hgweb.wsgi に切り替えましたが、違いはありませんでした。
私が発見したのは、一部のフックがリモートでは呼び出されないということです。
に切り替えたとき
[hooks]
incoming= set >&2
フックタグとコミットは呼び出されないようですが、受信と変更セットは呼び出されます。他は確認していません。
動作するようになったので、hgweb.cgi に戻しましたが、すべて同じように動作します。
私が見つけたこの理由はリダイレクトとは何の関係もありません stdout
に stderr
. 。Wiki ページでわかるように、Wiki の現在のバージョンでは指定されていません。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
追伸:私の場合は、むしろ特定のブランチの先頭に更新するので、 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
追伸:~のおかげで http://jf.blogs.teximus.com/2011/01/running-mercurial-hg-serve-on-linux.html