foozy@708: \chapter{Handling repository events with hooks} foozy@708: \label{chap:hook} foozy@708: foozy@708: Mercurial は、リポジトリに発生したイベントに応じて、 foozy@708: 自動的な処理を実行する強力な仕組みを提供しています。 foozy@708: 幾つかの状況では、 foozy@708: イベントに対する Mercurial の応答結果を制御することもできます。 foozy@708: foozy@708: Mercurial が利用するこれらの処理は、 foozy@708: \emph{フック}(hook)と呼ばれています。 foozy@708: 構成管理システムによってはフックを``トリガ''と呼ぶこともありますが、 foozy@708: これらは共に同じ考え方を指します。 foozy@708: foozy@708: \section{An overview of hooks in Mercurial} foozy@708: foozy@708: Mercurial が提供するフックの簡単なリストを示します。 foozy@708: これらのフックに関する詳細は \ref{sec:hook:ref}~節で説明します。 foozy@708: foozy@708: \begin{description} foozy@708: foozy@708: \item[\small\hook{changegroup}] foozy@708: 外部リポジトリからチェンジセット群が持ち込まれた後に実行されます。 foozy@708: foozy@708: \item[\small\hook{commit}] foozy@708: ローカルリポジトリにおいて新たなチェンジセットが作成された後に実行されます。 foozy@708: foozy@708: \item[\small\hook{incoming}] foozy@708: 外部リポジトリから持ち込まれた新たなチェンジセット毎に1回づつ実行されます。 foozy@708: 持ち込まれたチェンジセットの\emph{まとまり}の単位で起動される foozy@708: \hook{changegroup} との違いに注意してください。 foozy@708: foozy@708: \item[\small\hook{outgoing}] foozy@708: 外部リポジトリへチェンジセット群が転送された後に実行されます。 foozy@708: foozy@708: \item[\small\hook{prechangegroup}] foozy@708: 外部リポジトリからチェンジセット群が持ち込まれる前に実行されます。 foozy@708: foozy@708: \item[\small\hook{precommit}] foozy@708: 制御用。 foozy@708: ローカルリポジトリへのコミット前に実行されます。 foozy@708: foozy@708: \item[\small\hook{preoutgoing}] foozy@708: 制御用。 foozy@708: 外部リポジトリへチェンジセット群が転送される前に実行されます。 foozy@708: foozy@708: \item[\small\hook{pretag}] foozy@708: 制御用。タグ生成前に実行されます。 foozy@708: foozy@708: \item[\small\hook{pretxnchangegroup}] foozy@708: 制御用。 foozy@708: 外部からローカルリポジトリへとチェンジセット群が持ち込まれた際に、 foozy@708: 変更を恒久的なものにするトランザクションが完了する前に実行されます。 foozy@708: foozy@708: \item[\small\hook{pretxncommit}] foozy@708: 制御用。 foozy@708: ローカルリポジトリにおいて新たなチェンジセットが作成された際に、 foozy@708: 変更を恒久的なものにするトランザクションが完了する前に実行されます。 foozy@708: foozy@708: \item[\small\hook{preupdate}] foozy@708: 制御用。 foozy@708: 作業領域ディレクトリの更新・マージが実施される前に実行されます。 foozy@708: foozy@708: \item[\small\hook{tag}] foozy@708: タグが生成された後に実行されます。 foozy@708: foozy@708: \item[\small\hook{update}] foozy@708: 作業領域ディレクトリの更新・マージが完了した後に実行されます。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: ``制御用''と書かれているフックは、 foozy@708: 処理の継続性の可否を判定する機能を持っています。 foozy@708: フックの実行が成功した場合、 foozy@708: フックに対応する処理は継続されますが、 foozy@708: フックの実行が失敗した場合、 foozy@708: 対応する処理は許可されないか実行しなかったことになります foozy@708: (どちらになるかはフックに応じて決まります)。 foozy@708: foozy@708: \section{Hooks and security} foozy@708: foozy@708: \subsection{Hooks are run with your privileges} foozy@708: foozy@708: リポジトリにおいて Mercurial のコマンドを実行し、 foozy@708: そのコマンドがフックを起動することになった場合、 foozy@708: \emph{コマンド実行者の}システム上において、 foozy@708: \emph{コマンド実行者の}ユーザアカウントにより、 foozy@708: \emph{コマンド実行者の}権限レベルで実行されます。 foozy@708: フックは任意の実行コードですから、 foozy@708: 十分な配慮を持って扱う必要があります。 foozy@708: 誰が作成して何をするフックなのかを熟知している確信無しに、 foozy@708: フックをインストールしないでください。 foozy@708: foozy@708: 時には、 foozy@708: 自分でインストールしたのではないフックに晒されるかもしれません。 foozy@708: 馴染みの無いシステム上で Mercurial を使用する際には、 foozy@708: Mercurial がシステム共通の \hgrc\ foozy@708: ファイルで定義されたフックを実行するかもしれません。 foozy@708: foozy@708: 他のユーザが所有するリポジトリで作業する場合、 foozy@708: Mercurial はそのユーザのリポジトリで定義されたフックを実行できますが、 foozy@708: それは``あなたの''権限で実行されます。 foozy@708: 例えば、あるリポジトリから \hgcmd{pull} した際に、 foozy@708: そのリポジトリの \sfilename{.hg/hgrc} ファイルが foozy@708: \hook{outgoing} フックを定義していた場合、 foozy@708: リモートリポジトリの所有者で無かったとしても、 foozy@708: フックはあなたのアカウントで実行されます。 foozy@708: foozy@708: \begin{note} foozy@708: この原則は、 foozy@708: ローカルファイルシステムかネットワークファイルシステム上のリポジトリから foozy@708: pull した場合にのみ適用されます。 foozy@708: http や ssh 経由で pull した場合、 foozy@708: フックが実行される際のアカウントは、 foozy@708: サーバ上でサーバプロセスを実行するアカウントです。 foozy@708: \end{note} foozy@708: foozy@708: リポジトリにおけるフックの定義状況を見るには、 foozy@708: \hgcmdargs{showconfig}{hooks} コマンドが利用できます。 foozy@708: あるリポジトリで作業中に、 foozy@708: 自分の所有していない別なリポジトリ foozy@708: との連携(例: \hgcmd{pull} ないし \hgcmd{incoming})が必要になった場合、 foozy@708: リポジトリのフック定義状況を確認すべきです\footnote{訳注: foozy@708: ``XXX'' が付与されていることから原文未完?}。 foozy@708: foozy@708: \subsection{Hooks do not propagate} foozy@708: foozy@708: Mercurial では、フック設定の構成管理は行われないため、 foozy@708: リポジトリの clone ないし pull の際に、 foozy@708: フック設定は伝播しません。 foozy@708: その理由は簡単で、フックは完全に任意の実行コードだからです。 foozy@708: フックは、 foozy@708: コマンド実行者のマシン上において、 foozy@708: コマンド実行者のユーザアカウントにより、 foozy@708: コマンド実行者の権限レベルで実行されます。 foozy@708: foozy@708: フックの構成管理の実装は、 foozy@708: 構成管理システム利用者のアカウントを弱体化させる上で、 foozy@708: 容易に悪用可能な方法を提供してしまうため、 foozy@708: あらゆる分散構成管理システムにとって極めて無謀と言えます。 foozy@708: foozy@708: Mercurial はフックを伝播しないため、 foozy@708: 共通のプロジェクトでの他のメンバーとの連携の際には、 foozy@708: 彼らが自分と同じ Mercurial のフックを利用していることや、 foozy@708: 彼らがフックを正しく設定していることを仮定してはいけません。 foozy@708: 彼らにフックの使用を期待するのであれば、 foozy@708: それを文書化すべきです。 foozy@708: foozy@708: 企業のイントラネットの場合、 foozy@708: 例えば Mercurial の``標準的な''インストールを NFS 上で行い、 foozy@708: 組織で共通の \hgrc\ ファイルで全てのユーザが使用すべきフックを定義する、 foozy@708: といったことが可能であるため、 foozy@708: フックの管理は幾分容易になります。 foozy@708: しかし、それでも後述するような制限が生じます。 foozy@708: foozy@708: \subsection{Hooks can be overridden} foozy@708: foozy@708: Mercurial は、再定義によるフックの上書きを許しています。 foozy@708: フック指定に空文字列を設定することでフック設定を無効にすることもできますし、 foozy@708: 希望通りに振る舞いを変えることもできます。 foozy@708: foozy@708: 幾つかのフックを定義した、 foozy@708: マシンないし組織共通の \hgrc\ ファイルを配備したとしても、 foozy@708: 利用者によるフックの無効化や上書きが行われる可能性があることを、 foozy@708: 理解しておく必要があります。 foozy@708: foozy@708: \subsection{Ensuring that critical hooks are run} foozy@708: foozy@708: 他のメンバーに実施して欲しくない事柄について纏めた方針を、 foozy@708: 強制したいことも時にはあるかもしれません。 foozy@708: 例えば、全てのチェンジセットには必ず厳密なテスト一式に通っていて欲しい、 foozy@708: と思うかもしれません。 foozy@708: この要望を実現するために、 foozy@708: 組織共通の \hgrc\ ファイルでフックを定義したとしても、 foozy@708: モバイル PC からアクセスする遠隔ユーザ等には機能しませんし、 foozy@708: 勿論ローカルユーザにとってもフックの上書きによって無効化が可能です。 foozy@708: foozy@708: (プロジェクトにおける)Mercurial の利用方針として、 foozy@708: メンバーが変更伝播する際には、 foozy@708: 関門の機能を果たすように適切に設定された周知の``正規''サーバを通す、 foozy@708: と策定することで、 foozy@708: フックによる利用方針の強制を代替することが可能です。 foozy@708: foozy@708: 実現方法の一つとして、 foozy@708: ソーシャルエンジニアリングと技術の組み合わせによるものがあります。 foozy@708: アクセス制限付きアカウントを用意し、 foozy@708: 当該アカウントで管理されたリポジトリに、 foozy@708: 各メンバーはネットワーク経由で変更を push できるようにしますが、 foozy@708: そのアカウントでログインしたり、 foozy@708: 通常のシェルコマンドを実行したりできないようにします。 foozy@708: このままでは、 foozy@708: メンバーは「ゴミ」を含むようなチェンジセットのコミットも可能です。 foozy@708: foozy@708: メンバーが pull するサーバーへと誰かがチェンジセットを push した場合、 foozy@708: そのチェンジセットが永続化される前にサーバーはテストを実施\footnote{ foozy@708: 訳注: テスト実施はフックで実現されますが、 foozy@708: (1) フックの実行はアクセス制限付きアカウントの権限で実行され、 foozy@708: (2) リモートからの push の場合はフックの上書きができない、 foozy@708: ということから、セキュリティ・フック設定の問題が共に解消されます。}し、 foozy@708: テスト一式に通らなければそのチェンジセットを拒否します。 foozy@708: メンバーがこのフィルタサーバからしかチェンジセットの pull をしないのであれば、 foozy@708: メンバーが pull する全てのチェンジセットは、 foozy@708: 自動的に点検されていることが保証されます。 foozy@708: foozy@708: \section{Care with \texttt{pretxn} hooks in a shared-access repository} foozy@708: \label{sec:hook:carepretxn} foozy@708: foozy@708: 多くの人により共有されているリポジトリに対して、 foozy@708: フックによる自動実行を設定する場合、 foozy@708: 実施方式には注意が必要です。 foozy@708: foozy@708: Mercurial がリポジトリにロックを掛けるのは、 foozy@708: リポジトリに書き込みを行う時だけであり、 foozy@708: 且つロックに対して注意を払うのは、 foozy@708: Mercurial の書き込み処理の部分的な箇所だけです。 foozy@708: 書き込みロックは、 foozy@708: 複数の処理の同時書き込みによるリポジトリ破損を防ぐことで、 foozy@708: お互いの書き込み内容を保護します。 foozy@708: foozy@708: Mercurial はデータの読み込み書き出し順序に注意を払っていますから、 foozy@708: リポジトリからのデータ読み込みの際にロックは必要ありません。 foozy@708: Mercurial がリポジトリからデータを読み込む際には、 foozy@708: ロックに対して注意を払いません。 foozy@708: ロックを必要としないこの仕組みは、 foozy@708: 性能と平行性を大きく向上させています。 foozy@708: foozy@708: しかしながら、 foozy@708: 「ロックされない」ということは、 foozy@708: それを知らないと、 foozy@708: 大きな性能向上と引き換えにトラブル発生の潜在的な危険性を持っています。 foozy@708: この危険性について説明するには、 foozy@708: リポジトリへのチェンジセットの追加、 foozy@708: およびそれらチェンジセットの読み出しを、 foozy@708: Mercurial がどういった手順で行うかについて、 foozy@708: 幾分詳細な知識が必要となります。 foozy@708: foozy@708: Mercurial がメタデータを\emph{書き出す}際には、 foozy@708: 対象ファイルにメタデータを直接書き出します。 foozy@708: 最初に filelog にメタデータを書き出し、 foozy@708: 次に manifest のデータ(これには、 foozy@708: filelog に書き出した新しいデータへのポインタが含まれます)、 foozy@708: そしてchangelogのデータ(これには、 foozy@708: manifest に書き出した新しいデータへのポインタが含まれます)が書き出されます。 foozy@708: 個々のファイルへの最初の書き出しの前に、 foozy@708: Mercurial は個々のファイルの終端位置情報をトランザクションログに記録します。 foozy@708: Mercurial によりトランザクションが巻き戻される際には、 foozy@708: トランザクション開始時点のサイズにまで個々のファイルが切り詰められます。 foozy@708: foozy@708: Mercurial がメタデータを\emph{読み込む}際には、 foozy@708: changelog を読み込んだ後でその他のファイルの読み込みを行います。 foozy@708: データ読み込みの際には、 foozy@708: 先に読み込んだ changelog から到達可能な foozy@708: manifest や filelog の部分にしかアクセスしないので、 foozy@708: 不十分な書き出し中のデータを読むことはありません。 foozy@708: foozy@708: 幾つかの制御用フックの(\hook{pretxncommit} や \hook{pretxnchangegroup}) foozy@708: は、トランザクションの完了直前に実行されます。 foozy@708: この時点で全てのメタデータは書き出し済みですが、 foozy@708: Mercurial はトランザクションを巻き戻すことで、 foozy@708: 新たに書き出されたデータを破棄することができます。 foozy@708: foozy@708: トランザクション完了前のチェンジセットは永続性が確定しておらず、 foozy@708: そのため``本当に存在する''とみなすことができないことから、 foozy@708: トランザクション完了前に実行される制御用フックが終了までに長時間を要する場合、 foozy@708: 永続性が確定していないチェンジセットのメタデータが、 foozy@708: 平行して動作している他の処理により読み出される時間帯が発生します。 foozy@708: フックの実行時間が長くなる程、この時間帯が長くなります。 foozy@708: foozy@708: \subsection{The problem illustrated} foozy@708: foozy@708: 原則的に \hook{pretxnchangegroup} フックは、 foozy@708: 集約用リポジトリでの受け入れ前に、 foozy@708: 新規チェンジセットのビルドやテストを自動化するのに適しています。 foozy@708: この用法は foozy@708: ``ビルドを失敗させる''変更が集約用リポジトリに反映されないことを保証します。 foozy@708: しかし、 foozy@708: \hook{pretxnchangegroup} フックによるテスト途上の変更を、 foozy@708: 他の利用者が pull できてしまうようでは、 foozy@708: テストの有用性が無くなってしまいます。 foozy@708: リポジトリ内容の整合性に疑いを持たない利用者は、 foozy@708: ビルドを失敗させる潜在的な可能性を持つテスト未実施の変更を、 foozy@708: 自身のリポジトリへと反映してしまうからです。 foozy@708: foozy@708: このような難題への最も安全な技術的解法は、 foozy@708: ``門番''リポジトリの利用を\emph{単方向}に限定してしまうことです。 foozy@708: 門番リポジトリは、 foozy@708: 外部からのチェンジセットの push は許しても、 foozy@708: pull はできないようにします foozy@708: (\hook{preoutgoing} フックでそのような行為を禁止します)。 foozy@708: 新しいチェンジセットにおけるビルドないしテストが成功したならば、 foozy@708: そのチェンジセットを別なリポジトリへと push するように foozy@708: \hook{changegroup} フックを設定し、 foozy@708: 利用者はそちらのリポジトリから pull \emph{できる}ようにしましょう。 foozy@708: foozy@708: 実際問題、 foozy@708: このような集約されたボトルネックを設けることは、 foozy@708: あまり良いアイディアではなく(XXXX ?)、 foozy@708: In practice, putting a centralised bottleneck like this in place is foozy@708: not often a good idea foozy@708: トランザクションの漏洩\footnote{訳注: foozy@708: 永続化未確定のチェンジセットが見えてしまうこと}は問題になりません。 foozy@708: チェンジセットを取り扱う時間よりもそれをテストするのに時間を要する状況では、 foozy@708: プロジェクトの大きさ---およびビルド・テストに要する時間 foozy@708: ---が増加するほど、 foozy@708: ``購入前の試用''手法により壁の内側に素早く走りこめます。XXXXX ???? foozy@708: As the size of a project---and the time it takes to foozy@708: build and test---grows, you rapidly run into a wall with this ``try foozy@708: before you buy'' approach, where you have more changesets to test than foozy@708: time in which to deal with them. foozy@708: 避けられない結果は、 foozy@708: すべてが巻き込まれた部分におけるフラストレーションです。XXXXXXX ???? foozy@708: The inevitable result is frustration foozy@708: on the part of all involved. foozy@708: foozy@708: より大規模化可能な手法は、 foozy@708: push 前に各自でビルド・テストを実施してもらい、 foozy@708: push の \emph{後}に中央で自動的にビルド・テストを行うことで、 foozy@708: 全てのチェンジセットが良好であることを確認する、というものです。 foozy@708: この手法の利点は、 foozy@708: リポジトリにおけるチェンジセットの受理進度に関して、 foozy@708: 制限が課されることが無い点にあります。 foozy@708: foozy@708: \section{A short tutorial on using hooks} foozy@708: \label{sec:hook:simple} foozy@708: foozy@708: Mercurial のフックは簡単に書けます。 foozy@708: \hgcmd{commit} が完了した際に実行され、 foozy@708: 作成したばかりのチェンジセットのハッシュ値を表示するだけの、 foozy@708: 簡単なフックを書いてみましょう。 foozy@708: foozy@708: \begin{figure}[ht] foozy@708: \interaction{hook.simple.init} foozy@708: \caption{A simple hook that runs when a changeset is committed} foozy@708: \label{ex:hook:init} foozy@708: \end{figure} foozy@708: foozy@708: 全てのフックは、\ref{ex:hook:init} の例における形式を踏襲します。 foozy@708: \hgrc\ ファイルの foozy@708: \rcsection{hooks} セクションにエントリを追加します。 foozy@708: 左辺は実行契機になるイベントの名前で、 foozy@708: 右辺は実行される処理です。 foozy@708: 見てわかるように、 foozy@708: フックにおいては任意のシェルコマンドを実行できます。 foozy@708: 環境変数 foozy@708: (例における \envar{HG\_NODE} を参照してください)を用いて、 foozy@708: Mercurial はフックに付加情報を渡します。 foozy@708: foozy@708: \subsection{Performing multiple actions per event} foozy@708: foozy@708: \ref{ex:hook:ext} の例に示すような、 foozy@708: 特定の種類のイベントに対して1つ以上のフックを定義したい状況が、 foozy@708: しばしば発生することでしょう。 foozy@708: Mercurial では、 foozy@708: フック名の末尾に\emph{拡張子}を付与することで、 foozy@708: 同一イベントへの複数フックの定義が可能になります。 foozy@708: 拡張子の付与は、 foozy@708: フック名に、 foozy@708: ピリオド(``\texttt{.}'' 文字)と任意に選んだ文字列を続けることで行います。 foozy@708: 例えば、 foozy@708: \texttt{commit} が発生した場合、 foozy@708: Mercurial は foozy@708: \texttt{commit.foo} および foozy@708: \texttt{commit.bar} フックを実行します。 foozy@708: foozy@708: \begin{figure}[ht] foozy@708: \interaction{hook.simple.ext} foozy@708: \label{ex:hook:ext} foozy@708: \caption{Defining a second \hook{commit} hook} foozy@708: \end{figure} foozy@708: foozy@708: あるイベントに複数のフックが定義されている際に、 foozy@708: その実行順序を明確に定義するために、 foozy@708: Mercurial はフックを拡張子で整列させ、 foozy@708: フックコマンドをこの整列された順序で実行します。 foozy@708: 上記の例では、 foozy@708: \texttt{commit.foo} foozy@708: の前に foozy@708: \texttt{commit.bar} を、 foozy@708: これらの前に foozy@708: \texttt{commit} を実行します。 foozy@708: foozy@708: 新しいフックを定義する際に、 foozy@708: 何らかの説明的な拡張子を使用するのは良いアイディアです。 foozy@708: そうすることで、 foozy@708: そのフックが何をするためのものかを思い出しやすくなります。 foozy@708: フックの実行が失敗した場合、 foozy@708: フック名と拡張子を含むエラーメッセージが表示されますから、 foozy@708: フックが失敗した理由に関して、 foozy@708: 説明的な拡張子から即製のヒントを得ることができます foozy@708: (例に関しては、\ref{sec:hook:perm}~節を参照してください)。 foozy@708: foozy@708: \subsection{Controlling whether an activity can proceed} foozy@708: \label{sec:hook:perm} foozy@708: foozy@708: 先の例では、 foozy@708: コミット操作が完了した後で実行される foozy@708: \hook{commit} フックを使用しました。 foozy@708: このフックは、 foozy@708: 操作が完了した後で実行される Mercurial のフックの1つです。 foozy@708: これらのフックは、操作そのものに影響を及ぼすことはありません。 foozy@708: foozy@708: Mercurial では、 foozy@708: 操作が開始される前や、 foozy@708: 操作が完了するまでの間に発生するイベントが定義されています。 foozy@708: これらのイベントの際に起動されるフックは、 foozy@708: 操作を継続可能か中断すべきかを判断することができます。 foozy@708: foozy@708: \hook{pretxncommit} フックは、 foozy@708: コミット操作が概ね終了した後、コミットが完了する前の段階で起動されます。 foozy@708: 言い換えるなら、 foozy@708: チェンジセットを表すメタデータがディスクに書き込まれてはいるものの、 foozy@708: トランザクションが未だ完了していない状況で起動されます。 foozy@708: \hook{pretxncommit} フックは、 foozy@708: トランザクションを完了させるのか、 foozy@708: あるいは巻き戻すべきかを決定することができます。 foozy@708: foozy@708: \hook{pretxncommit} フックが終了状態値として0を返却した場合、 foozy@708: トランザクションは完了し、コミット操作は終了しますので、 foozy@708: \hook{commit} フックが実行されます。 foozy@708: \hook{pretxncommit} フックが終了状態として非0を返却した場合、 foozy@708: トランザクションは巻き戻され、 foozy@708: チェンジセットを表すメタデータは削除され、 foozy@708: \hook{commit} フックは実行されません。 foozy@708: foozy@708: \begin{figure}[ht] foozy@708: \interaction{hook.simple.pretxncommit} foozy@708: \label{ex:hook:pretxncommit} foozy@708: \caption{Using the \hook{pretxncommit} hook to control commits} foozy@708: \end{figure} foozy@708: foozy@708: 例~\ref{ex:hook:pretxncommit} 中のフックは、 foozy@708: コミット時のコメントがバグIDを含んでいることを確認しています。 foozy@708: コメントがバグIDを含んでいる場合、コミットは完了します。 foozy@708: そうでなければ、コミット操作は巻き戻されます。 foozy@708: foozy@708: \section{Writing your own hooks} foozy@708: foozy@708: \hggopt{-v} オプション付き、 foozy@708: あるいは\rcitem{ui}{verbose} 設定項目を``true''にして foozy@708: Mercurial を実行するのが、 foozy@708: フック実装の際には有用であることに気付くかもしれません。 foozy@708: このようにして Mercurial を実行することで、 foozy@708: それぞれのフックを起動する際に事前にメッセージを表示します。 foozy@708: foozy@708: \subsection{Choosing how your hook should run} foozy@708: \label{sec:hook:lang} foozy@708: foozy@708: フックを実装する際には、通常のプログラム---典型的にはシェルスクリプト--- foozy@708: としても実装できますが、 foozy@708: Python 関数としても実装でき、 foozy@708: その場合は Mercurial プロセス内で実行されます。 foozy@708: foozy@708: 外部プログラムとしてフックを実装する利点は、 foozy@708: Mercurial の内部事情に関して知る必要が無い点にあります。 foozy@708: 付加的な情報の取得のために、 foozy@708: 通常の Mercurial コマンドを起動することもできます。 foozy@708: その利点と引き換えに、外部(プログラムとしての)フックは、 foozy@708: プロセス内フックよりも低速\footnote{訳注: foozy@708: 後述されますが、 foozy@708: 外部プログラムによるフックが「低速」であるのは、 foozy@708: (1)外部プロセスとしてのフック起動と、 foozy@708: (2)Mercurial リポジトリへのアクセスに関する部分で、 foozy@708: 外部プロセスの実行そのものが低速なわけではありません。}です。 foozy@708: foozy@708: Python 関数によるプロセス内フックは、 foozy@708: 全ての Mercurial API にアクセスでき、 foozy@708: 他のプロセスを``生成''する必要はありませんので、 foozy@708: 基本的に外部フックよりも高速です。 foozy@708: フックが必要とする多くの情報の入手も、 foozy@708: Mercurial コマンドから得るよりも、 foozy@708: Mercurial API から得る方が容易です。 foozy@708: foozy@708: Python の利用が苦にならないか、 foozy@708: 高い実行性能が要求される場合、 foozy@708: Python でのフック実装を選択すべきです。 foozy@708: しかしながら、 foozy@708: 簡単なフックで、 foozy@708: 性能を気にする必要が無い(おそらく多くのフックがそうです)のであれば、 foozy@708: シェルスクリプトでの実装で十分です。 foozy@708: foozy@708: \subsection{Hook parameters} foozy@708: \label{sec:hook:param} foozy@708: foozy@708: Mercurial がフックを起動する際には、 foozy@708: 明確に定義されたパラメータがフックに渡されます。 foozy@708: Python でのフック実装の場合、 foozy@708: パラメータはキーワード引数としてフック関数に渡されます。 foozy@708: 外部プログラムでのフック実装の場合、 foozy@708: パラメータは環境変数として渡されます。 foozy@708: foozy@708: フック実装が Python ・シェルスクリプトのいずれであるかで、 foozy@708: フック固有のパラメータ名とその値が決まります\footnote{訳注: foozy@708: 原文は foozy@708: 「Whether your hook is written in Python or as a shell script, the foozy@708: hook-specific parameter names and values will be the ``same''」} foozy@708: 真偽値パラメータは、Python フックでは真偽値型として表現されますが、 foozy@708: 外部フックに対しては ``1''(``true'' 値として)ないし foozy@708: ``0''(``false'' 値として)を持つ環境変数で表現されます。 foozy@708: フックパラメータが \texttt{foo} という名前である場合、 foozy@708: Python フックのキーワード引数の名前も \texttt{foo} ですが、 foozy@708: 外部フックの環境変数名は \texttt{HG\_FOO} となります。 foozy@708: foozy@708: \subsection{Hook return values and activity control} foozy@708: foozy@708: 実行が成功したフックは、外部フックの場合は終了コード0で、 foozy@708: プロセス内フックの場合は真偽値``False''で終了しなければなりません foozy@708: \footnote{訳注:Mercurial の配布物に含まれる hgext 配下のフックは、 foozy@708: 結構な確率で、 foozy@708: False 無しの return や、 foozy@708: 明示的な return 無しの実装ですが、 foozy@708: Python の言語仕様上、 foozy@708: これらは False と``ほぼ等価''な None とみなされます。}。 foozy@708: フックの実行失敗は、 foozy@708: 外部フックの場合は非0の終了コードで、 foozy@708: プロセス内フックの場合は真偽値``true''で表されます。 foozy@708: プロセス内ふっくが例外を浮揚した場合、 foozy@708: フック実行は失敗したと見做されます。 foozy@708: foozy@708: 操作の継続性を制御できるフックの場合、 foozy@708: 0/false は継続の``許可''を、 foozy@708: 非0/true/例外は``拒否''を意味します。 foozy@708: foozy@708: \subsection{Writing an external hook} foozy@708: foozy@708: \hgrc\ ファイルに外部フックを記述した場合、 foozy@708: \hgrc\ ファイルに記述したフックの内容は、 foozy@708: シェルプロセスに渡され、 foozy@708: そのシェルプロセスによって解釈されます。 foozy@708: これは、フック記述の本体に、 foozy@708: 通常のシェルコマンドラインと同様の構造を用いることができる、 foozy@708: ということを意味しています。 foozy@708: foozy@708: 実行可能なフックは、 foozy@708: 常にリポジトリのルートディレクトリ直下で実行されます。 foozy@708: foozy@708: 個々のフックパラメータは環境変数経由で渡されますが、 foozy@708: 環境変数名には、 foozy@708: 大文字化され、接頭辞として``\texttt{HG\_}''が付与された名前が用いられます。 foozy@708: foozy@708: フックパラメータを例外とすれば、 foozy@708: Mercurial はフック実行時に環境変数の改変を行いません。 foozy@708: それぞれに異なる環境変数設定をしている多くのユーザによって実行される、 foozy@708: 組織全体で共用されるフックを実装する際には、 foozy@708: この知識が役に立つでしょう。 foozy@708: 複数ユーザにより実行される状況下では、 foozy@708: フックの試験環境で設定されていた環境変数が、 foozy@708: 実行時に設定されていることを期待してはいけません。 foozy@708: foozy@708: \subsection{Telling Mercurial to use an in-process hook} foozy@708: foozy@708: プロセス内フックを \hgrc\ ファイルで設定する際の文法は、 foozy@708: 実行可能フック\footnote{訳注: 「外部フック」の意 foozy@708: }設定の際のそれとは少々異なります foozy@708: フック設定は、 foozy@708: 接頭辞``\texttt{python:}''に続き、 foozy@708: フックとして使用する呼び出し可能オブジェクト\footnote{訳注: foozy@708: callable object}の完全修飾された名前が記述されていなければなりません。 foozy@708: foozy@708: フック定義が存在するモジュールは、 foozy@708: フック実行時に自動的に import されます。 foozy@708: モジュール名と \envar{PYTHONPATH} 設定が正しければ、 foozy@708: きっと動作する筈です\footnote{訳注: ``just work'' のニュアンスは?}。 foozy@708: foozy@708: 以下に示す \hgrc\ ファイルの引用例は、 foozy@708: 前述した表記に関する文法と意味を例示しています。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [hooks] foozy@708: commit.example = python:mymodule.submodule.myhook foozy@708: \end{codesample2} foozy@708: foozy@708: Mercurial が \texttt{commit.example} フックを起動する際には、 foozy@708: \texttt{mymodule.submodule} を import し、 foozy@708: \texttt{myhook} という名前の呼び出し可能オブジェクトを探し出して起動します。 foozy@708: foozy@708: \subsection{Writing an in-process hook} foozy@708: foozy@708: 以下に示す最も単純なプロセス内フックは、 foozy@708: フックとしては何もしませんが、 foozy@708: フック API の基本的な概要を例示できます。 foozy@708: foozy@708: \begin{codesample2} foozy@708: def myhook(ui, repo, **kwargs): foozy@708: pass foozy@708: \end{codesample2} foozy@708: foozy@708: Python フック\footnote{訳注:プロセス内フックの意}の最初の引数は、 foozy@708: 常に \pymodclass{mercurial.ui}{ui} オブジェクトです。 foozy@708: 第2引数はリポジトリオブジェクトですが、 foozy@708: 現在の Mercurial の実装では、 foozy@708: そのインスタンスは常に \pymodclass{mercurial.localrepo}{localrepository} です。 foozy@708: これらに続くその他の引数はキーワード引数として渡されます。 foozy@708: 渡される内容は起動されるフック(の種類)に依存しますが、 foozy@708: 上記例における \texttt{**kwargs} のように、 foozy@708: キーワード引数辞書に落とし込む\footnote{XXXXX: foozy@708: Python 固有の訳語を確認}ことで、 foozy@708: 興味の無い引数を無視することができます。 foozy@708: foozy@708: \section{Some hook examples} foozy@708: foozy@708: \subsection{Writing meaningful commit messages} foozy@708: foozy@708: 有用なコミットメッセージが非常に短い、 foozy@708: という状況は想像し難いものがあります。 foozy@708: 図~\ref{ex:hook:msglen.go} に示す単純な foozy@708: \hook{pretxncommit} フックは、 foozy@708: 10バイトよりも短いメッセージでのチェンジセットのコミットを妨げます。 foozy@708: foozy@708: \begin{figure}[ht] foozy@708: \interaction{hook.msglen.go} foozy@708: \caption{A hook that forbids overly short commit messages} foozy@708: \label{ex:hook:msglen.go} foozy@708: \end{figure} foozy@708: foozy@708: \subsection{Checking for trailing whitespace} foozy@708: foozy@708: コミットに関する興味深いフックの利用は、 foozy@708: 綺麗なコードでの実装を補助するというものです。 foozy@708: 簡単な``綺麗なコード''の例としては、 foozy@708: 変更が追加する新しい行には``末尾空白''が含まれていてはならない、 foozy@708: という格言があります。 foozy@708: 末尾空白とは、 foozy@708: 空白文字およびタブ(tab)文字の連続が行末にあることを意味します。 foozy@708: 多くの場合、 foozy@708: 末尾空白は必要の無い不可視の雑音みたいなものですが、 foozy@708: 時には問題を含むことから、 foozy@708: それらが取り除かれることを望みます。 foozy@708: foozy@708: \hook{precommit} と \hook{pretxncommit} のいずれのフックでも、 foozy@708: 末尾空白問題を通知することが可能です。 foozy@708: \hook{precommit} フックを使用した場合、 foozy@708: フックはコミット対象ファイルを知ることができないので、 foozy@708: リポジトリ中の変更されたファイル全てに対して末尾空白を確認してしまいます。 foozy@708: そうすると、 foozy@708: ファイル \filename{foo} の変更のみをコミットしたい場合でも、 foozy@708: \filename{bar} ファイルが末尾空白を含んでいたなら、 foozy@708: \hook{precommit} フックでのチェックは、 foozy@708: \filename{bar} の問題を理由に \filename{foo} のコミットを妨げてしまいます。 foozy@708: これではいけません。 foozy@708: foozy@708: \hook{pretxncommit} フックで実現する場合、 foozy@708: コミットのトランザクションが完了する直前までチェックが行われません。 foozy@708: このため、末尾空白問題の確認を、 foozy@708: 厳密にコミット対象のファイルだけに行うことができます。 foozy@708: しかし、 foozy@708: コミットメッセージを対話的に入力した後であっても、 foozy@708: フックの実行が失敗\footnote{ foozy@708: 訳注: 末尾空白が検出されることでの「失敗」}した場合、 foozy@708: トランザクションは巻き戻されてしまいますので、 foozy@708: 末尾空白を取り除いた後で再び \hgcmd{commit} コマンド実行した際には、 foozy@708: もう一度コミットメッセージを入力する必要があります。 foozy@708: foozy@708: \begin{figure}[ht] foozy@708: \interaction{hook.ws.simple} foozy@708: \caption{A simple hook that checks for trailing whitespace} foozy@708: \label{ex:hook:ws.simple} foozy@708: \end{figure} foozy@708: foozy@708: 図~\ref{ex:hook:ws.simple} では、 foozy@708: 末尾空白をチェックする簡単な foozy@708: \hook{pretxncommit} フックを紹介しています。 foozy@708: このフックは短いですが、非常に有用です。 foozy@708: 変更により何れかのファイルに対して末尾空白を含む行が追加された場合、 foozy@708: このフックはエラーステータスで終了しますが、 foozy@708: 不愉快なファイルや行の特定を補助する情報を何ら表示しません\footnote{訳注: foozy@708: フック実行のコマンドラインからわかるように、 foozy@708: export 出力(= patch 形式)に対して (e)grep を適用していますから、 foozy@708: ファイル名や行番号に対しては何ら認識されていません。}。 foozy@708: このフックは、 foozy@708: 改変されていない行には注意を払わず、 foozy@708: 末尾空白問題を持ち込む行にのみ注意を払う、 foozy@708: という優れた特質も持っています。 foozy@708: foozy@708: \begin{figure}[ht] foozy@708: \interaction{hook.ws.better} foozy@708: \caption{A better trailing whitespace hook} foozy@708: \label{ex:hook:ws.better} foozy@708: \end{figure} foozy@708: foozy@708: 図~\ref{ex:hook:ws.better} は先の例よりは複雑ですが、 foozy@708: より有用なフックの例を示しています\footnote{訳注: foozy@708: check\_whitespace.py の内容が不明。 foozy@708: 図中でソースを cat すべき XXXX}。 foozy@708: このフックは unified diff 形式を解析して、 foozy@708: 末尾空白を追加する行の有無を判定し、 foozy@708: そのようなファイルの名前と行番号を表示します。 foozy@708: それに加えてこのフックは、 foozy@708: チェンジセットが末尾空白を追加することを検知した場合、 foozy@708: 実行を終了して Mercurial にトランザクションの巻き戻しを伝える前に、 foozy@708: コミットメッセージを保存してそのファイル名を表示しますので、 foozy@708: 問題点を修正した後のコミットの際には、 foozy@708: \hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{filename}} foozy@708: を使ってコミットメッセージを再利用することができます。 foozy@708: foozy@708: 図~\ref{ex:hook:ws.better} foozy@708: ファイルから末尾空白を取り除く foozy@708: \command{perl} の一行記述の用法を示します。 foozy@708: この方法はここに再掲するに足るだけの、 foozy@708: 簡潔さと有用性を持っています\footnote{訳注: foozy@708: コードの表示が(HTML 形式だと)2行に分割されている XXXX}。 foozy@708: foozy@708: \begin{codesample2} foozy@708: perl -pi -e 's,\\s+\$,,' filename foozy@708: \end{codesample2} foozy@708: foozy@708: \section{Bundled hooks} foozy@708: foozy@708: Mercurial の配布版には、幾つかのフックが添付されています。 foozy@708: 添付フックは Mercurial ソースツリーの foozy@708: \dirname{hgext} ディレクトリに格納されています。 foozy@708: Mercurial のバイナリ配布版を使用している場合には、 foozy@708: パッケージのインストーラーが foozy@708: Mercurial をインストールした位置にある foozy@708: \dirname{hgext} ディレクトリに格納されています。 foozy@708: foozy@708: \subsection{\hgext{acl}---access control for parts of a repository} foozy@708: foozy@708: \hgext{acl} 拡張により、 foozy@708: ネットワーク上のサーバに対してチェンジセットを foozy@708: push 可能な遠隔ユーザを制限することができます。 foozy@708: リポジトリの一部(勿論全体も)を保護することができますので、 foozy@708: 特定のユーザに対しては、 foozy@708: 保護された部分に影響を及ぼさないチェンジセットのみの push が可能です。 foozy@708: foozy@708: この拡張は foozy@708: push 対象のチェンジセットをコミットしたユーザ\emph{ではなく}、 foozy@708: push を実施するユーザの身元情報を元にアクセス制御を行います。 foozy@708: 遠隔ユーザを認証する監禁(lock-downed)サーバが存在する環境で、 foozy@708: 特定のユーザだけが監禁サーバへのチェンジセットの foozy@708: push が許されることを確実にしたい場合でなければ、 foozy@708: このフックの使用は意味がありません。 foozy@708: foozy@708: \subsubsection{Configuring the \hook{acl} hook} foozy@708: foozy@708: 持ち込まれるチェンジセットを管理するために、 foozy@708: \hgext{acl} フックは foozy@708: \hook{pretxnchangegroup} フックとして用います。 foozy@708: \hook{pretxnchangegroup} フックとして用いられることで、 foozy@708: 外来のチェンジセットにより変更されるファイルを知ることができるため、 foozy@708: ``禁止されている''ファイルへの変更を行うチェンジセット群に対しては、 foozy@708: トランザクションの巻き戻しが行われます。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [hooks] foozy@708: pretxnchangegroup.acl = python:hgext.acl.hook foozy@708: \end{codesample2} foozy@708: foozy@708: \hgext{acl} 拡張は3つのセクションで設定されます。 foozy@708: foozy@708: \rcsection{acl} セクションには、 foozy@708: フックが注意を払うべき外来チェンジセットの出所を列挙する foozy@708: \rcitem{acl}{sources} エントリだけが記述されます。 foozy@708: 通常はこのセクションを設定する必要はありません。 foozy@708: foozy@708: \begin{description} foozy@708: \item[\rcitem{acl}{serve}] リモートリポジトリからの http ないし ssh foozy@708: 経由のチェンジセットに対して制御を行います。 foozy@708: これは \rcitem{acl}{sources} の既定値で、 foozy@708: 通常はこの設定項目に対して行う唯一の設定です。 foozy@708: foozy@708: \item[\rcitem{acl}{pull}] ローカルリポジトリからの foozy@708: pull 経由のチェンジセットに対して制御を行います。 foozy@708: foozy@708: \item[\rcitem{acl}{push}] ローカルリポジトリからの foozy@708: push 経由のチェンジセットに対して制御を行います。 foozy@708: foozy@708: \item[\rcitem{acl}{bundle}] 他のリポジトリからの foozy@708: bundle 経由のチェンジセットに対して制御を行います。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: \rcsection{acl.allow} セクションは、 foozy@708: リポジトリへのチェンジセット追加を許可されているユーザを決定します。 foozy@708: このセクションが存在しない場合、 foozy@708: 明示的に禁止されていないユーザは、 foozy@708: 誰でもチェンジセットの追加をできます。 foozy@708: このセクションが存在する場合、 foozy@708: 明示的に許可されていないユーザは、 foozy@708: 誰もチェンジセットの追加ができません( foozy@708: ですので、このセクションを空にした場合、 foozy@708: 全てのユーザがチェンジセットの追加を禁止されます)。 foozy@708: foozy@708: \rcsection{acl.deny} セクションは、 foozy@708: リポジトリへのチェンジセット追加を禁止されているユーザを決定します。 foozy@708: このセクションが記述されない場合、 foozy@708: 全てのユーザはチェンジセットの追加を許可されます\footnote{訳注: foozy@708: 原文は「no users are denied」ですが、 foozy@708: acl.py の実装上は「禁止しない」と「許可」は等価です。}。 foozy@708: foozy@708: \rcsection{acl.allow} および \rcsection{acl.deny} foozy@708: セクションの文法は同一です。 foozy@708: 各エントリの左辺は、 foozy@708: リポジトリルート相対でのファイルないしディレクトリのマッチングパターンで、 foozy@708: 右辺はユーザ名となっています。 foozy@708: foozy@708: 以下の例では、 foozy@708: ユーザ \texttt{docwriter} がリポジトリの foozy@708: \dirname{docs} 配下に対する変更の foozy@708: push のみが許可されている一方で、 foozy@708: ユーザ \texttt{intern} は foozy@708: \dirname{source/sensitive} foozy@708: 以外の任意のディレクトリ・ファイルに対する変更を foozy@708: push 可能です foozy@708: \footnote{訳注: foozy@708: 設定の判定順序は (1) 禁止 (2) 許可の順序で行われ、 foozy@708: (1) 禁止設定があり、当該ユーザのアクセスが明示的に禁止されている場合と、 foozy@708: (2) 許可設定があり、当該ユーザのアクセスが明示的に許可されて「いない」場合に、 foozy@708: 不正アクセスとみなされ、 foozy@708: それ以外の場合はアクセスが許可されます。}。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [acl.allow] foozy@708: docs/** = docwriter foozy@708: foozy@708: [acl.deny] foozy@708: source/sensitive/** = intern foozy@708: \end{codesample2} foozy@708: foozy@708: \subsubsection{Testing and troubleshooting} foozy@708: foozy@708: \hgext{acl} フックを試してみたい場合、 foozy@708: Mercurial のデバッグ出力を有効にして実行しましょう。 foozy@708: \hggopt{--debug} オプションを指定し難い(あるいは不可能な) foozy@708: サーバ上で実行することもあるでしょうから、 foozy@708: サーバ側の \hgrc ファイルでデバッグ出力を有効化できることをお忘れなく。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [ui] foozy@708: debug = true foozy@708: \end{codesample2} foozy@708: foozy@708: これを有効にすることで、 foozy@708: 当該ユーザによる push foozy@708: を許可・禁止する理由を判断するに足る情報を表示することでしょう。 foozy@708: foozy@708: \subsection{\hgext{bugzilla}---integration with Bugzilla} foozy@708: foozy@708: \hgext{bugzilla} 拡張は、 foozy@708: コミットメッセージにバグIDを検知した際に foozy@708: Bugzilla バグへのコメント追加を行います。 foozy@708: このフックを共有サーバに設定することで、 foozy@708: このサーバへのリモートからの変更伝播の際には、 foozy@708: 常にこのフックが実行されます。 foozy@708: foozy@708: このフックは Bugzilla バグに、 foozy@708: 以下のようなコメントを追加します foozy@708: (方法は後述しますが、コメント内容は変更できます)。 foozy@708: foozy@708: \begin{codesample2} foozy@708: Changeset aad8b264143a, made by Joe User in foozy@708: the frobnitz repository, refers to this bug. foozy@708: foozy@708: For complete details, see foozy@708: http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a foozy@708: foozy@708: Changeset description: foozy@708: Fix bug 10483 by guarding against some NULL pointers foozy@708: \end{codesample2} foozy@708: foozy@708: このフックの価値は、 foozy@708: チェンジセット(のコミットメッセージ)がバグを参照している際に、 foozy@708: バグ情報を更新する手順を自動化する点にあります。 foozy@708: フックの設定を適切に行うことで、 foozy@708: Bugzilla バグから参照元チェンジセットへと、 foozy@708: 一直線に到達することが容易になります。 foozy@708: foozy@708: このフックの実装を足掛りにして、 foozy@708: より高度な Bugzilla との統合を図ることも可能です。 foozy@708: 例えば: foozy@708: foozy@708: \begin{itemize} foozy@708: \item サーバに push される全てのチェンジセットには、 foozy@708: コミットメッセージに適切なバグ~IDが含まれていることを要求: foozy@708: この場合、\hook{pretxncommit} foozy@708: フックに当該条件を検証するフックを設定するのが良いでしょう。 foozy@708: コミットメッセージがバグ~IDを含まないチェンジセットは、 foozy@708: フックによって拒否されるようになります。 foozy@708: foozy@708: \item 新規のチェンジセットに対して、 foozy@708: 簡単なコメントの付与と同様に、 foozy@708: バグの\emph{状態}の自動的な変更を許可: foozy@708: 例えば、``fixed bug 31337'' というコミットメッセージの文字列を、 foozy@708: バグ 31337 の状態の ``requires testing'' への更新、 foozy@708: と認識させる、といった拡張も考えられます。 foozy@708: foozy@708: \end{itemize} foozy@708: foozy@708: \subsubsection{Configuring the \hook{bugzilla} hook} foozy@708: \label{sec:hook:bugzilla:config} foozy@708: foozy@708: \hook{bugzilla} フックは、 foozy@708: サーバ側の \hgrc\ 中で \hook{incoming} フックとして設定しなければなりません。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [hooks] foozy@708: incoming.bugzilla = python:hgext.bugzilla.hook foozy@708: \end{codesample2} foozy@708: foozy@708: 機能特化されたフックの性質と、 foozy@708: Bugzilla が元々この種の統合を念頭に置いていないことから、 foozy@708: このフックの設定は何かと複雑になります。 foozy@708: foozy@708: フックの設定に先立って、 foozy@708: フックが実行されるホスト(群)に対して、 foozy@708: MySQL の Python バインディングをインストールしてください。 foozy@708: 対象ホストにおいてバイナリパッケージが見当たらない場合、 foozy@708: \cite{web:mysql-python} からダウンロードできます。 foozy@708: foozy@708: フックの設定は、 foozy@708: \hgrc\ ファイルの foozy@708: \rcsection{bugzilla} セクションに記述されます。 foozy@708: foozy@708: \begin{description} foozy@708: foozy@708: \item[\rcitem{bugzilla}{version}] サーバにインストールされている foozy@708: Bugzilla のバージョン。 foozy@708: Bugzilla のデータベーススキーマは時折変更されますので、 foozy@708: どのスキーマが使用されているのかを厳密に知っている必要があります。 foozy@708: 今のところ、サポート対象は \texttt{2.16} のみです。 foozy@708: foozy@708: \item[\rcitem{bugzilla}{host}] Bugzilla のデータが格納されている foozy@708: MySQL サーバが稼動しているホスト名。 foozy@708: MySQL サーバは、\hook{bugzilla} フックが実行される全てのホストに対して、 foozy@708: 接続を許可している必要があります。 foozy@708: foozy@708: \item[\rcitem{bugzilla}{user}] MySQL サーバへの接続時に使用するユーザ名。 foozy@708: MySQL サーバは、\hook{bugzilla} フックが実行される全てのホストに対して、 foozy@708: このユーザ名での接続を許可している必要があります。 foozy@708: このユーザは、 foozy@708: Bugzilla が使用するテーブルに対して読み取り・変更の両方の権限が必要です。 foozy@708: この項目の既定値は、 foozy@708: MySQL サーバにおける Bugzilla の標準的なユーザ名である foozy@708: \texttt{bugs} です。 foozy@708: foozy@708: \item[\rcitem{bugzilla}{password}] 上記ユーザの foozy@708: MySQL サーバにおけるパスワード。 foozy@708: この値は平文で格納されるため、 foozy@708: 権限を持たないユーザがこの情報の書かれた \hgrc foozy@708: ファイルを覗くことが無いようにしなければなりません。 foozy@708: foozy@708: \item[\rcitem{bugzilla}{db}] MySQL サーバにおける foozy@708: Bugzilla データベースの名前。 foozy@708: この項目の既定値は、 foozy@708: MySQL サーバにおける Bugzilla の標準的なデータベース名である foozy@708: \texttt{bugs} です。 foozy@708: foozy@708: \item[\rcitem{bugzilla}{notify}] フックによるバグへのコメント付与時に、 foozy@708: Bugzilla による購読者への電子メール通知を実施したい場合、 foozy@708: データベースを更新する毎にコマンドを実行させる必要があります。 foozy@708: 実行するコマンドは Bugzilla のインストール場所に依存しますが、 foozy@708: \dirname{/var/www/html/bugzilla} にインストールしたとすると、 foozy@708: 通常は以下のようになります。 foozy@708: foozy@708: \begin{codesample4} foozy@708: cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com foozy@708: \end{codesample4} foozy@708: foozy@708: Bugzilla の \texttt{processmail} プログラムは、 foozy@708: バグ~ID(フックにより ``\texttt{\%s}'' が バグ~ID に置換されます)と、 foozy@708: 電子メールアドレスを必要とします。 foozy@708: このプログラムは、 foozy@708: 実行時ディレクトリへのファイル書き出しの権限も必要とします。 foozy@708: Bugzilla とフックが同じサーバ上にインストールされていない場合、 foozy@708: Bugzilla がインストールされているサーバ上で foozy@708: \texttt{processmail} を起動する方法を見つけ出す必要があります。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: \subsubsection{Mapping committer names to Bugzilla user names} foozy@708: foozy@708: 既定状態の \hgext{bugzilla} フックは、 foozy@708: チェンジセットをコミットしたユーザの電子メールアドレスを、 foozy@708: バグの更新を行う Bugzilla ユーザ名として使用することを試みます。 foozy@708: この挙動が状況に即さない場合、 foozy@708: \rcsection{usermap} セクションを使用して、 foozy@708: チェンジセットをコミットしたユーザの電子メールアドレスを foozy@708: Bugzilla のユーザ名に変換することができます。 foozy@708: foozy@708: \rcsection{usermap} セクションの個々の要素は、 foozy@708: 左辺に電子メールアドレス、 foozy@708: 右辺に Bugzilla ユーザ名を保持します。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [usermap] foozy@708: jane.user@example.com = jane foozy@708: \end{codesample2} foozy@708: foozy@708: 通常の \hgrc ファイルに foozy@708: \rcsection{usermap} データを直接保持することもできますが、 foozy@708: \hgext{bugzilla} フックに外部の foozy@708: \filename{usermap} ファイルから情報を読み込むように指示することもできます。 foozy@708: 後者の場合、例えば \filename{usermap} データそのものを、 foozy@708: 利用者が改変可能なリポジトリに格納することもできます。 foozy@708: そうすることで、 foozy@708: 利用者自身が foozy@708: \rcitem{bugzilla}{usermap} 中の各自の要素を保守することができます。 foozy@708: この場合の \hgrc\ ファイルは以下のように記述されます。 foozy@708: foozy@708: \begin{codesample2} foozy@708: # 通常の hgrc ファイルは usermap 外部ファイルを参照 foozy@708: [bugzilla] foozy@708: usermap = /home/hg/repos/userdata/bugzilla-usermap.conf foozy@708: \end{codesample2} foozy@708: foozy@708: \filename{usermap} が参照するファイルの内容は、 foozy@708: 以下のようになります。 foozy@708: foozy@708: \begin{codesample2} foozy@708: # bugzilla-usermap.conf は hg リポジトリ内に配置 foozy@708: [usermap] foozy@708: stephanie@example.com = steph foozy@708: \end{codesample2} foozy@708: foozy@708: \subsubsection{Configuring the text that gets added to a bug} foozy@708: foozy@708: Mercurial のテンプレート形式で記述することで、 foozy@708: \hgext{bugzilla} フックが追加するコメントの内容を設定することが可能です。 foozy@708: 幾つかの(\rcsection{bugzilla} セクションにおける) \hgrc\ 要素により、 foozy@708: (テンプレートの?)振る舞いを制御することができます。 foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{strip}] URL における部分パス名(a foozy@708: partial path for a URL)を生成する際に、 foozy@708: リポジトリにおけるパス名から取り除くパス要素の数を指定します。 foozy@708: 例えば、サーバにおけるリポジトリ群が \dirname{/home/hg/repos} 配下にあり、 foozy@708: \dirname{/home/hg/repos/app/tests} のリポジトリを対象とする場合、 foozy@708: \texttt{strip} を \texttt{4} とすることで、 foozy@708: \dirname{app/tests} という部分パスを得ることができます。 foozy@708: \hgext{bugzilla} フックはこの部分パス名を、 foozy@708: テンプレートの適用の際に \texttt{webroot} という名前で利用可能にします。 foozy@708: foozy@708: \item[\texttt{template}] 使用するテンプレートテキストを指定します。 foozy@708: 通常のチェンジセット関連の置換に加えて、 foozy@708: このテンプレートでは \texttt{hgweb}(後述例にあるように foozy@708: \texttt{hgweb} 項目で設定します) foozy@708: および \texttt{webroot}(前述のように foozy@708: \texttt{strip} によって生成されるパスです)が使用できます。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: これらに加えて、 foozy@708: \hgrc\ ファイルの \rcsection{web} セクションに foozy@708: \rcitem{web}{baseurl} 項目を追加することができます。 foozy@708: Bugzilla コメントからのチェンジセット参照に使用するリンクの foozy@708: URL を構築する際の基底文字列として foozy@708: \hgext{bugzilla} フックはテンプレート展開の際にこの値を使用します。 foozy@708: 例えば: foozy@708: foozy@708: \begin{codesample2} foozy@708: [web] foozy@708: baseurl = http://hg.domain.com/ foozy@708: \end{codesample2} foozy@708: foozy@708: \hgext{bugzilla} フックの設定例を以下に示します\footnote{訳注: foozy@708: 原文の ``\\n'' が正しく機能していないため、 foozy@708: 例示のレイアウトが乱れている}。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [bugzilla] foozy@708: host = bugzilla.example.com foozy@708: password = mypassword foozy@708: version = 2.16 foozy@708: # サーバ側リポジトリは /home/hg/repos にあるため、 foozy@708: # 冒頭の 4 つのセパレータ\footnote{訳注: パス区切り ``/''}を除外 foozy@708: strip = 4 foozy@708: hgweb = http://hg.example.com/ foozy@708: usermap = /home/hg/repos/notify/bugzilla.conf foozy@708: template = Changeset \{node|short\}, made by \{author\} in the \{webroot\} foozy@708: repo, refers to this bug.\\nFor complete details, see foozy@708: \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset foozy@708: description:\\n\\t\{desc|tabindent\} foozy@708: \end{codesample2} foozy@708: foozy@708: \subsubsection{Testing and troubleshooting} foozy@708: foozy@708: \hgext{bugzilla} フック設定において最も良くある問題は、 foozy@708: Bugzilla の \filename{processmail} スクリプト実行に関するものと、 foozy@708: コミットユーザ名から Bugzilla ユーザ名への変換に関するものです。 foozy@708: foozy@708: 先の \ref{sec:hook:bugzilla:config}~節からの説明で述べたように、 foozy@708: Mercurial プロセスをサーバで実行するユーザが、 foozy@708: \filename{processmail} スクリプトを実行するユーザでもあります。 foozy@708: \filename{processmail} スクリプトは foozy@708: Bugzilla が設定ディレクトリ中のファイルに何らかの情報を書き出す契機となるため、 foozy@708: 通常 Bugzilla の設定ファイルは foozy@708: Bugzilla が動作するウェブサーバの実行者の権限下にあります。 foozy@708: foozy@708: \filename{processmail} 実行の際には、 foozy@708: \command{sudo} コマンドを利用するなどして適切なユーザ権限で実行しましょう。 foozy@708: \filename{sudoers} フィルの設定例を以下に示します。 foozy@708: foozy@708: \begin{codesample2} foozy@708: hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s foozy@708: \end{codesample2} foozy@708: foozy@708: この例では、\texttt{hg\_user} ユーザは、 foozy@708: \filename{processmail-wrapper} プログラムを foozy@708: \texttt{httpd\_user} ユーザの権限下で実行することができます。 foozy@708: foozy@708: \filename{processmail} プログラムは foozy@708: Bugzilla をインストールしたディレクトリ直下での実行が必要ですが、 foozy@708: \filename{sudoers} ファイルにはそのような制約を記述することができないので、 foozy@708: このような間接実行のためのラッパースクリプトが必要となります。 foozy@708: ラッパースクリプトの内容は以下のように簡単なものです。 foozy@708: foozy@708: \begin{codesample2} foozy@708: #!/bin/sh foozy@708: cd `dirname $0` && ./processmail "$1" nobody@example.com foozy@708: \end{codesample2} foozy@708: foozy@708: \filename{processmail} foozy@708: に指定する電子メールアドレスは、 foozy@708: どのようなものでも構いません。 foozy@708: foozy@708: \rcsection{usermap} が正しく設定されていない場合、 foozy@708: チェンジセットをサーバに push した際に foozy@708: \hgext{bugzilla} フックによりエラーメッセージが表示されます。 foozy@708: エラーメッセージは以下のようなものです。 foozy@708: foozy@708: \begin{codesample2} foozy@708: cannot find bugzilla user id for john.q.public@example.com foozy@708: \end{codesample2} foozy@708: foozy@708: このメッセージは、 foozy@708: コミットしたユーザの電子メールアドレス foozy@708: \texttt{john.q.public@example.com} foozy@708: が有効な Bugzilla ユーザ名ではないか、 foozy@708: \texttt{john.q.public@example.com} foozy@708: を有効な Bugzilla ユーザ名に変換するエントリが foozy@708: rcsection{usermap} に記述されていないことを意味します。 foozy@708: foozy@708: \subsection{\hgext{notify}---send email notifications} foozy@708: foozy@708: Mercurial の組み込みウェブサーバにより、 foozy@708: 全てのリポジトリに対してチェンジセット情報の RSS 配信機能が提供されますが、 foozy@708: 電子メールによる変更通知が選択される場合が多いです。 foozy@708: \hgext{notify} フックは、 foozy@708: 購読者が興味を持つ新たなチェンジセットごとに、 foozy@708: 電子メールアドレス(群)に宛てて通知を行います。 foozy@708: foozy@708: \hgext{notify} はテンプレート駆動型のフックですので、 foozy@708: \hgext{bugzilla} フックと同様に、 foozy@708: 送信される通知の内容をカスタマイズすることができます。 foozy@708: foozy@708: 既定状態では foozy@708: \hgext{notify} フックはチェンジセットごとの差分情報を取り込みますが、 foozy@708: 差分情報の量を制限したり、 foozy@708: この機能を完全に停止することもできます。 foozy@708: 購読者による変更の即時レビューを想定する場合、 foozy@708: 指定された URL をクリックするよりも、 foozy@708: 差分情報を取り込むほうが有用です。 foozy@708: foozy@708: \subsubsection{Configuring the \hgext{notify} hook} foozy@708: foozy@708: \hgext{notify} フックは、 foozy@708: 新たなチェンジセットごとに1通の電子メールを送信することもできれば、 foozy@708: (単独の \hgcmd{pull} ないし \hgcmd{push} によりリポジトリに追加される foozy@708: )新たなチェンジセット群ごとに送信することもできます。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [hooks] foozy@708: # チェンジセット群ごとに1通のメールを送信 foozy@708: changegroup.notify = python:hgext.notify.hook foozy@708: # チェンジセットごとに1通のメールを送信 foozy@708: incoming.notify = python:hgext.notify.hook foozy@708: \end{codesample2} foozy@708: foozy@708: このフックの設定情報は、 foozy@708: \hgrc\ ファイルの foozy@708: \rcsection{notify} セクションに記述されます。 foozy@708: foozy@708: \begin{description} foozy@708: \item[\rcitem{notify}{test}] 既定状態では、 foozy@708: このフックは全くメールを送信しません。 foozy@708: その替わり、送信する\emph{であろう}メッセージを表示します。 foozy@708: この項目を \texttt{false} にすることで電子メールが送信されるようになります。 foozy@708: 基底状態で電子メールの送信が停止されているのは、 foozy@708: この拡張(/フック)をきちんと設定するのには幾分かの試行錯誤が必要なので、 foozy@708: 設定試行中に``壊れた''通知を購読者に送信してしまうためです。 foozy@708: foozy@708: \item[\rcitem{notify}{config}] 購読情報を保持している設定ファイルへのパス。 foozy@708: この情報は \hgrc\ とは分離されているので、 foozy@708: このファイルそのものを対象リポジトリで管理することも可能です。 foozy@708: こうすることで、 foozy@708: 対象リポジトリを複製し、購読設定を更新した上で、 foozy@708: 変更をサーバに \hgcmd{push} で戻すことができます。 foozy@708: foozy@708: \item[\rcitem{notify}{strip}] リポジトリに対する購読者の有無を判定する際に、 foozy@708: リポジトリのパス冒頭から取り除くパス区切りの数\footnote{訳注: foozy@708: ここでは strip 対象を foozy@708: ``leading path separator characters'' と表現しているが、 foozy@708: \rcsection{bugzilla} の説明では foozy@708: ``leading path elements'' と表現している。 foozy@708: 統一的な表現が必要と思われる。}。 foozy@708: 例えば、 foozy@708: サーバ上のリポジトリが \dirname{/home/hg/repos} 配下にあり、 foozy@708: \hgext{notify} が foozy@708: \dirname{/home/hg/repos/shared/test} というリポジトリを認識している場合、 foozy@708: \rcitem{notify}{strip} を \texttt{4} に設定することで foozy@708: \hgext{notify} による購読者とのパターンマッチングは、 foozy@708: パスを \dirname{shared/test} と認識した上で行われます。 foozy@708: foozy@708: \item[\rcitem{notify}{template}] foozy@708: メッセージ送信の際に使用されるテンプレートテキスト。 foozy@708: このテンプレートは、メッセージのヘッダとボディの両方の内容を指定します。 foozy@708: foozy@708: \item[\rcitem{notify}{maxdiff}] foozy@708: メッセージ末尾に付与される差分データの最大行数。 foozy@708: この行数よりも大きい場合、差分データは切り詰められます。 foozy@708: この値の既定値は 300 に設定されています。 foozy@708: この値を \texttt{0} にした場合、 foozy@708: 通知の電子メールに差分データは付与されません。 foozy@708: foozy@708: \item[\rcitem{notify}{sources}] 配慮すべきチェンジセットの由来元の一覧。 foozy@708: この設定により例えば、 foozy@708: 遠隔ユーザがサーバを経由して当該リポジトリへ foozy@708: \hgcmd{push} したチェンジセットに対してのみ foozy@708: \hgext{notify} が電子メールで通知する、 foozy@708: といった設定をすることができます。 foozy@708: ここで記述可能な由来元の一覧は、\ref{sec:hook:sources}~節を参照してください。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: \rcsection{web} セクションで foozy@708: \rcitem{web}{baseurl} 項目を設定している場合、 foozy@708: テンプレート中で \texttt{webroot} として使用することができます。 foozy@708: foozy@708: \hgext{notify} 設定情報の一式を以下に示します。 foozy@708: foozy@708: \begin{codesample2} foozy@708: [notify] foozy@708: # 実際に電子メールを送るか否か foozy@708: test = false foozy@708: # 通知を行うリポジトリ自身の中に置かれている購読者情報 foozy@708: config = /home/hg/repos/notify/notify.conf foozy@708: # リポジトリが /home/hg/repos 配下にあるので "/" 文字を4つ除去 foozy@708: strip = 4 foozy@708: template = X-Hg-Repo: \{webroot\}\\n\\\\ foozy@708: Subject: \{webroot\}: \{desc|firstline|strip\}\\n\\\\ foozy@708: From: \{author\}\\n\\\\ foozy@708: \\n\\\\ foozy@708: changeset \{node|short\} in \{root\}\\n\\\\ foozy@708: details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\}\\n\\\\ foozy@708: description:\\n\\\\ foozy@708: \\t\{desc|tabindent|strip\} foozy@708: foozy@708: [web] foozy@708: baseurl = http://hg.example.com/ foozy@708: \end{codesample2} foozy@708: foozy@708: この設定により、 foozy@708: 以下のようなメッセージが生成されます。 foozy@708: foozy@708: \begin{codesample2} foozy@708: X-Hg-Repo: tests/slave foozy@708: Subject: tests/slave: Handle error case when slave has no buffers foozy@708: Date: Wed, 2 Aug 2006 15:25:46 -0700 (PDT) foozy@708: foozy@708: changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave foozy@708: details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5 foozy@708: description: foozy@708: Handle error case when slave has no buffers foozy@708: diffs (54 lines): foozy@708: foozy@708: diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h foozy@708: --- a/include/tests.h Wed Aug 02 15:19:52 2006 -0700 foozy@708: +++ b/include/tests.h Wed Aug 02 15:25:26 2006 -0700 foozy@708: @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h) foozy@708: [...snip...] foozy@708: \end{codesample2} foozy@708: foozy@708: \subsubsection{Testing and troubleshooting} foozy@708: foozy@708: 既定値のままでは \hgext{notify} 拡張は foozy@708: \emph{一切のメールを送信しません}ので、 foozy@708: \rcitem{notify}{test} 項目を明示的に foozy@708: \texttt{false} で設定することを忘れないでください。 foozy@708: この設定を行うまでは、 foozy@708: \hgext{notify} 拡張は送信する\emph{であろう}メッセージを表示します。 foozy@708: foozy@708: \section{Information for writers of hooks} foozy@708: \label{sec:hook:ref} foozy@708: foozy@708: \subsection{In-process hook execution} foozy@708: foozy@708: プロセス内フックは、以下の引数形式で起動されます。 foozy@708: foozy@708: \begin{codesample2} foozy@708: def myhook(ui, repo, **kwargs): foozy@708: pass foozy@708: \end{codesample2} foozy@708: foozy@708: \texttt{ui} 引数は foozy@708: \pymodclass{mercurial.ui}{ui} オブジェクト、 foozy@708: \texttt{repo} 引数は foozy@708: \pymodclass{mercurial.localrepo}{localrepository} オブジェクトです。 foozy@708: \texttt{**kwargs} パラメータの持つ名前と値は、 foozy@708: 起動されるフックの種類に依存し、 foozy@708: 以下の共通の特徴を持っています。 foozy@708: foozy@708: \begin{itemize} foozy@708: \item \texttt{node} ないし \texttt{parent\emph{N}} という名前の引数は、 foozy@708: 16進数のチェンジセットIDを保持しています。 foozy@708: 空の文字列は、 foozy@708: 0 続きの文字列の代わりに ``null チェンジセットID'' を意味します。 foozy@708: foozy@708: \item \texttt{url} という名前の引数は、 foozy@708: それが特定可能であれば、遠隔リポジトリの URL を表します。 foozy@708: foozy@708: \item 真偽値引数は、Python の \texttt{bool} オブジェクトで表されます。 foozy@708: foozy@708: \end{itemize} foozy@708: foozy@708: プロセス内フックは、 foozy@708: (外部フックがリポジトリ直下で実行されるのと違い) foozy@708: プロセスの作業ディレクトリを変更せずに起動されます。 foozy@708: プロセスの作業ディレクトリを移動させると、 foozy@708: Mercurial API の呼び出しが失敗する要因と成りえますので、 foozy@708: プロセス内フックは作業ディレクトリを変更してはいけません。 foozy@708: foozy@708: (プロセス内)フックが真偽値 ``false'' を返却した場合、 foozy@708: フック呼び出しは成功したものとみなされます。 foozy@708: 真偽値 ``true'' が返却されるか、 foozy@708: 例外が浮揚された場合、 foozy@708: フック呼び出しは失敗したものとみなされます。 foozy@708: 起動の慣習を理解するには、 foozy@708: ``失敗したか否かを通知する''と覚えるのが良いでしょう。 foozy@708: foozy@708: チェンジセットIDは、 foozy@708: Mercurial API が常用しているバイナリハッシュ形式ではなく、 foozy@708: Python フックに16進文字列の形式で渡される点に注意してください。 foozy@708: 16進ハッシュ値をバイナリハッシュ値形式に変換するには、 foozy@708: \pymodfunc{mercurial.node}{bin} 関数を使用してください。 foozy@708: foozy@708: \subsection{External hook execution} foozy@708: foozy@708: プロセス外フック(の起動文字列)は、 foozy@708: Mercurial を実行しているシェルに渡されます。 foozy@708: そのため、 foozy@708: 変数置換やコマンド出力のリダイレクトといった、 foozy@708: シェルの機能が利用可能です。 foozy@708: プロセス外フックは、 foozy@708: (プロセス内フックが Mercurial が起動されたディレクトリで実行されるのと違い) foozy@708: リポジトリルート直下で実行されます。 foozy@708: foozy@708: フック引数は、環境変数を経由して渡されます。 foozy@708: 個々の環境変数の名前は、 foozy@708: 大文字で且つ ``\texttt{HG\_}'' 接頭辞が付与された形式に変換されます。 foozy@708: 例えば、 foozy@708: 引数名が ``\texttt{node}'' の場合、 foozy@708: 当該引数を表す環境変数の名前は ``\texttt{HG\_NODE}'' となります。 foozy@708: foozy@708: 真偽値引数は、 foozy@708: ``true'' が文字列 ``\texttt{1}'' で、 foozy@708: ``false'' が文字列 ``\texttt{0}'' で表されます。 foozy@708: 環境変数 foozy@708: \envar{HG\_NODE}、\envar{HG\_PARENT1} ないし \envar{HG\_PARENT2} は、 foozy@708: チェンジセットIDを16進文字列で保持します。 foozy@708: ``空のチェンジセットID''は、 foozy@708: ``0'' の連続ではなく空の文字列として表現されます。 foozy@708: 環境変数 \envar{HG\_URL} は、 foozy@708: それが特定可能な場合に限り、遠隔リポジトリの URL を保持します。 foozy@708: foozy@708: プロセス外フックが終了コード0で終了した場合、 foozy@708: フックの実行は成功したものとみなされます。 foozy@708: 終了コードが0以外の場合、 foozy@708: フックの実行は失敗したものとみなされます。 foozy@708: foozy@708: \subsection{Finding out where changesets come from} foozy@708: foozy@708: ローカルリポジトリと他のリポジトリの間のチェンジセットの転送に関わるフックは、 foozy@708: ``向こう側''の情報を知ることができる場合があります。 foozy@708: Mercurial は、 foozy@708: チェンジセットが\emph{どのようにして}転送されたのかと、 foozy@708: 多くの場合、 foozy@708: \emph{どのリポジトリ}との間でチェンジセットが転送されるのかも知っています。 foozy@708: foozy@708: \subsubsection{Sources of changesets} foozy@708: \label{sec:hook:sources} foozy@708: foozy@708: Mercurial はリポジトリ間でチェンジセットを転送する意図を、 foozy@708: フックに対して事前(ないし事後に)通知します。 foozy@708: この情報は、 foozy@708: Python によるプロセス内フックの場合は \texttt{source} という名前の引数で、 foozy@708: 外部フックの場合は \envar{HG\_SOURCE} という名前の環境変数で、 foozy@708: Mercurial からフックに渡されます。 foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{serve}] 遠隔リポジトリとの間を、 foozy@708: http ないし ssh 経由でチェンジセットが転送されます。 foozy@708: foozy@708: \item[\texttt{pull}] あるリポジトリから他のリポジトリへ、 foozy@708: \hgcmd{pull} によりチェンジセットが転送されます。 foozy@708: foozy@708: \item[\texttt{push}] あるリポジトリから他のリポジトリへ、 foozy@708: \hgcmd{push} によりチェンジセットが転送されます。 foozy@708: foozy@708: \item[\texttt{bundle}] あるリポジトリから他のリポジトリへ、 foozy@708: \hgcmd{bundle} によりチェンジセットが転送されます。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: \subsubsection{Where changes are going---remote repository URLs} foozy@708: \label{sec:hook:url} foozy@708: foozy@708: Mercurial は、 foozy@708: リポジトリ間でのチェンジセット転送処理における``向こう側''の位置を、 foozy@708: 可能であればフックに知らせます。 foozy@708: この情報は、 foozy@708: Python によるプロセス内フックの場合は \texttt{url} という名前の引数で、 foozy@708: 外部フックの場合は \envar{HG\_URL} という名前の環境変数で、 foozy@708: Mercurial からフックに渡されます。 foozy@708: foozy@708: この情報は常にわかるというわけではありません。 foozy@708: http ないし ssh foozy@708: 経由でサービスを提供しているリポジトリにおいてフックが起動された場合、 foozy@708: Mercurial は遠隔リポジトリを特定することはできませんが、 foozy@708: クライアントがどのアドレスから接続しているのかは特定することができます。 foozy@708: このような場合、URL は以下のいずれかの形式になります。 foozy@708: foozy@708: \begin{itemize} foozy@708: \item \texttt{remote:ssh:\emph{ip-address}}---与えられた IP アドレスからの foozy@708: ssh 遠隔接続。 foozy@708: foozy@708: \item \texttt{remote:http:\emph{ip-address}}---与えられた IP アドレスからの foozy@708: http 遠隔接続。 foozy@708: クライアントが SSL を使用した場合、 foozy@708: \texttt{remote:https:\emph{ip-address}} 形式になります。 foozy@708: foozy@708: \item Empty---遠隔接続に関する情報を取得できなかった場合。 foozy@708: foozy@708: \end{itemize} foozy@708: foozy@708: \section{Hook reference} foozy@708: foozy@708: \subsection{\hook{changegroup}---after remote changesets added} foozy@708: \label{sec:hook:changegroup} foozy@708: foozy@708: このフックは、 foozy@708: 例えば \hgcmd{pull} ないし \hgcmd{unbundle} によって、 foozy@708: あらかじめ存在しているチェンジセットの一群が、 foozy@708: リポジトリに追加された後に実行されます。 foozy@708: これらの操作は任意個のチェンジセットを追加できますが、 foozy@708: このフックは各操作毎に1回づつ実行されます。 foozy@708: このことは、 foozy@708: チェンジセットがまとまって追加されるか否かに関わらず、 foozy@708: \hook{incoming} フックの実行がチェンジセット毎に実行されるのと対照的です。 foozy@708: foozy@708: 追加されたチェンジセットに対する自動化されたビルド・テストの開始契機としたり、 foozy@708: バグデータベースの更新、 foozy@708: リポジトリが新たなチェンジセットを取り込んだことの購読者への通知、 foozy@708: といったものが、 foozy@708: このフックに想定される用途の一部です。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: 追加される一群の中の最初のチェンジセットのID。 foozy@708: このチェンジセットから foozy@708: \index{tags!\texttt{tip}}\texttt{tip} foozy@708: まで(\texttt{tip} 自身も含む)の全てのチェンジセットが、 foozy@708: 単独の \hgcmd{pull}、\hgcmd{push} ないし \hgcmd{unbundle} foozy@708: 操作により追加されたことになります。 foozy@708: foozy@708: \item[\texttt{source}] 文字列。 foozy@708: チェンジセットの由来元を表します。 foozy@708: 詳細は\ref{sec:hook:sources}~節を参照してください。 foozy@708: foozy@708: \item[\texttt{url}] URL。 foozy@708: 特定できる場合に限り、遠隔リポジトリの場所を表します。 foozy@708: 詳細は\ref{sec:hook:url}~節を参照してください。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{incoming} (\ref{sec:hook:incoming}~節)、 foozy@708: \hook{prechangegroup} (\ref{sec:hook:prechangegroup}~節)、 foozy@708: \hook{pretxnchangegroup} (\ref{sec:hook:pretxnchangegroup}~節) foozy@708: foozy@708: \subsection{\hook{commit}---after a new changeset is created} foozy@708: \label{sec:hook:commit} foozy@708: foozy@708: このフックは、新しいチェンジセットが作成された後で実行されます。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{parent1}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットにとって、 foozy@708: 第1親となるチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{parent2}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットにとって、 foozy@708: 第2親となるチェンジセットのID。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: \hook{precommit} (\ref{sec:hook:precommit}~節)、 foozy@708: \hook{pretxncommit} (\ref{sec:hook:pretxncommit}~節) foozy@708: foozy@708: \subsection{\hook{incoming}---after one remote changeset is added} foozy@708: \label{sec:hook:incoming} foozy@708: foozy@708: このフックは、 foozy@708: 例えば \hgcmd{push} によって、 foozy@708: あらかじめ存在しているチェンジセットが、 foozy@708: リポジトリに追加された後に実行されます。 foozy@708: 複数のチェンジセットが単一の操作で追加された場合でも、 foozy@708: このフックは追加された個々のチェンジセット毎に実行されます。 foozy@708: foozy@708: このフックを \hook{changegroup} フック(\ref{sec:hook:changegroup}~節参照) foozy@708: と同様の目的に使用することができます。 foozy@708: 一群のチェンジセット毎のフック起動の方が便利な場合もありますが、 foozy@708: 時にはチェンジセットごとのフック起動も便利です。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: 新しく追加されたチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{source}] 文字列。 foozy@708: チェンジセットの由来元を表します。 foozy@708: 詳細は\ref{sec:hook:sources}~節を参照してください。 foozy@708: foozy@708: \item[\texttt{url}] URL。 foozy@708: 特定できる場合に限り、遠隔リポジトリの場所を表します。 foozy@708: 詳細は\ref{sec:hook:url}~節を参照してください。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{changegroup} (\ref{sec:hook:changegroup}~節)、 foozy@708: \hook{prechangegroup} (\ref{sec:hook:prechangegroup}~節)、 foozy@708: \hook{pretxnchangegroup} (\ref{sec:hook:pretxnchangegroup}~節) foozy@708: foozy@708: \subsection{\hook{outgoing}---after changesets are propagated} foozy@708: \label{sec:hook:outgoing} foozy@708: foozy@708: このフックは、 foozy@708: 例えば \hgcmd{push} ないし \hgcmd{bundle} によって、 foozy@708: 他のリポジトリへとチェンジセットの一群が伝播した後に実行されます。 foozy@708: foozy@708: チェンジセットが外部に伝播したことの管理者への通知などは、 foozy@708: このフックに想定される用途の1つです。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: 他のリポジトリへと伝播する一群の中の最初のチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{source}] 文字列。 foozy@708: 伝播操作の発行由来を表します(\ref{sec:hook:sources}~節を参照してください)。 foozy@708: 遠隔クライアントからの \hgcmd{pull} 要求の場合、 foozy@708: \texttt{source} は \texttt{serve} となります。 foozy@708: チェンジセット群を取得しようとするクライアントがローカルホスト上に居る場合、 foozy@708: クライアントの操作種別に応じて、 foozy@708: \texttt{source} の値は foozy@708: \texttt{bundle}、\texttt{pull} ないし \texttt{push} のいずれかになります。 foozy@708: foozy@708: \item[\texttt{url}] URL。 foozy@708: 特定できる場合に限り、遠隔リポジトリの場所を表します。 foozy@708: 詳細は\ref{sec:hook:url}~節を参照してください。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{preoutgoing} (\ref{sec:hook:preoutgoing}~節) foozy@708: foozy@708: \subsection{\hook{prechangegroup}---before starting to add remote changesets} foozy@708: \label{sec:hook:prechangegroup} foozy@708: foozy@708: この制御用フックは、 foozy@708: 他のリポジトリからのチェンジセット群の追加が foozy@708: Mercurial により開始される直前に実行されます。 foozy@708: foozy@708: このフックはチェンジセット群の転送開始が許可される前に実行されるため、 foozy@708: フック自体は追加されるチェンジセットに関する情報を得ることができません。 foozy@708: このフックの実行が失敗した場合、チェンジセット群は転送されません。 foozy@708: foozy@708: このフックの用途の一つに、 foozy@708: リポジトリに対する外部からのチェンジセット追加の禁止があります。 foozy@708: 例えば、 foozy@708: ローカルホスト上の管理者がリポジトリを変更できる一方で、 foozy@708: 利用者がサーバ経由で変更を \hgcmd{push} できないように、 foozy@708: 一時的ないし永久に``凍結''することもできます。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: foozy@708: \item[\texttt{source}] 文字列。 foozy@708: チェンジセットの由来元を表します。 foozy@708: 詳細は\ref{sec:hook:sources}~節を参照してください。 foozy@708: foozy@708: \item[\texttt{url}] URL。 foozy@708: 特定できる場合に限り、遠隔リポジトリの場所を表します。 foozy@708: 詳細は\ref{sec:hook:url}~節を参照してください。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{changegroup} (\ref{sec:hook:changegroup}~節)、 foozy@708: \hook{incoming} (\ref{sec:hook:incoming}~節)、 foozy@708: \hook{pretxnchangegroup} (\ref{sec:hook:pretxnchangegroup}~節) foozy@708: foozy@708: \subsection{\hook{precommit}---before starting to commit a changeset} foozy@708: \label{sec:hook:precommit} foozy@708: foozy@708: このフックは、 foozy@708: Mercurial が新たなチェンジセットをコミットする前に実行されます。 foozy@708: コミットされるファイル、コミットメッセージないし日付といった、 foozy@708: コミットに関するメタデータを foozy@708: Mercurial が揃える前に実行されます。 foozy@708: foozy@708: このフックの用途の一つに、 foozy@708: チェンジセットの受け入れを許す一方での、 foozy@708: 新たなチェンジセットのコミットの禁止があります。 foozy@708: 他の用途ととしては、 foozy@708: ビルドやテストを実施し、 foozy@708: それらが成功した場合にのみコミットを許可する、 foozy@708: というものもあります。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{parent1}] チェンジセットID。 foozy@708: 作業領域ディレクトリにとって、 foozy@708: 第1親となるチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{parent2}] チェンジセットID。 foozy@708: 作業領域ディレクトリにとって、 foozy@708: 第2親となるチェンジセットのID。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: コミットが進行した場合、 foozy@708: 作業領域ディレクトリの(両)親が、 foozy@708: 新たなチェンジセットの親となります。 foozy@708: foozy@708: 要別途参照: foozy@708: \hook{commit} (\ref{sec:hook:commit}~節)、 foozy@708: \hook{pretxncommit} (\ref{sec:hook:pretxncommit}~節) foozy@708: foozy@708: \subsection{\hook{preoutgoing}---before starting to propagate changesets} foozy@708: \label{sec:hook:preoutgoing} foozy@708: foozy@708: このフックは、 foozy@708: Mercurial が外部に転送されるチェンジセットを特定する直前に実行されます。 foozy@708: foozy@708: チェンジセットが他のリポジトリへ転送されるのを防ぐことは、 foozy@708: このフックに想定される用途の1うです。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{source}] 文字列。 foozy@708: 当該リポジトリに対するチェンジセットの取得要求の発行由来を表します foozy@708: (\ref{sec:hook:sources}~節を参照してください)。 foozy@708: このパラメータが取り得る値に関しては、 foozy@708: \hook{outgoing} の \texttt{source} パラメータに関する foozy@708: \ref{sec:hook:outgoing}~節の記述を参照してください。 foozy@708: foozy@708: \item[\texttt{url}] URL。 foozy@708: 特定できる場合に限り、遠隔リポジトリの場所を表します。 foozy@708: 詳細は\ref{sec:hook:url}~節を参照してください。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{outgoing} (\ref{sec:hook:outgoing}~節) foozy@708: foozy@708: \subsection{\hook{pretag}---before tagging a changeset} foozy@708: \label{sec:hook:pretag} foozy@708: foozy@708: この制御フックは、 foozy@708: タグが生成される前に実行されます。 foozy@708: フックの実行が成功した場合、タグの生成は継続され、 foozy@708: フックの実行が失敗した場合、タグは生成されません。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{local}] 真偽値。 foozy@708: タグがリポジトリに対してローカルなもの foozy@708: (\sfilename{.hg/localtags} に情報が格納される)なのか、 foozy@708: Mercurial に管理されるもの(\sfilename{.hgtags} に情報が格納) foozy@708: なのかを表します。 foozy@708: foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: タグ付けされるチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{tag}] 文字列。 foozy@708: 作成されるタグの名前。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 生成されるタグが構成管理対象となる場合、 foozy@708: \hook{precommit} (\ref{sec:hook:commit}~節)および foozy@708: \hook{pretxncommit} (\ref{sec:hook:pretxncommit}~節) foozy@708: フックも実行されます。 foozy@708: foozy@708: 要別途参照: foozy@708: \hook{tag} (\ref{sec:hook:tag}~節) foozy@708: foozy@708: \subsection{\hook{pretxnchangegroup}---before completing addition of foozy@708: remote changesets} foozy@708: \label{sec:hook:pretxnchangegroup} foozy@708: foozy@708: この制御フックは、 foozy@708: トランザクション--- foozy@708: このトランザクションは、 foozy@708: 他のリポジトリからの一群のチェンジセットの追加を管理します foozy@708: ---が完了する前に実行されます。 foozy@708: フックの実行が成功した場合、トランザクションは完了し、 foozy@708: 全てのチェンジセットがリポジトリにおいて永続化されます。 foozy@708: フックの実行が失敗した場合、 foozy@708: トランザクションは巻き戻され、 foozy@708: チェンジセットに関するデータは破棄されます。 foozy@708: foozy@708: このフックは、 foozy@708: 「ほぼ追加された」チェンジセットに関するメタデータにアクセスできますが、 foozy@708: 永続化されるような操作\footnote{訳注: foozy@708: 例えば、外部の DBMS へのデータ格納や、 foozy@708: 公開用ファイルへの書き出し等。} foozy@708: をこれらのデータに基づいて行うべきではありません foozy@708: 作業ディレクトリも変更すべきではありません。 foozy@708: foozy@708: このフックの実行中に、 foozy@708: 他の Mercurial プロセスが同じリポジトリにアクセスしてきた場合、 foozy@708: このプロセスからは、 foozy@708: 「ほぼ追加された」チェンジセットが永続化されたもののように見えます。 foozy@708: この状況を回避する手順を踏まないと、 foozy@708: 競合状態になりかねません。 foozy@708: foozy@708: このフックは、チェンジセット群に対する診断に利用可能です。 foozy@708: フックの実行が失敗した場合、 foozy@708: トランザクションが巻き戻され、 foozy@708: 全てのチェンジセットが``拒否''されます。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: 追加される一群の中の最初のチェンジセットのID。 foozy@708: このチェンジセットから foozy@708: \index{tags!\texttt{tip}}\texttt{tip} foozy@708: まで(\texttt{tip} 自身も含む)の全てのチェンジセットが、 foozy@708: 単独の \hgcmd{pull}、\hgcmd{push} ないし \hgcmd{unbundle} foozy@708: 操作により追加されたことになります。 foozy@708: foozy@708: \item[\texttt{source}] 文字列。 foozy@708: チェンジセットの由来元を表します。 foozy@708: 詳細は\ref{sec:hook:sources}~節を参照してください。 foozy@708: foozy@708: \item[\texttt{url}] URL。 foozy@708: 特定できる場合に限り、遠隔リポジトリの場所を表します。 foozy@708: 詳細は\ref{sec:hook:url}~節を参照してください。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{changegroup} (\ref{sec:hook:changegroup})、 foozy@708: \hook{incoming} (\ref{sec:hook:incoming})、 foozy@708: \hook{prechangegroup} (\ref{sec:hook:prechangegroup}) foozy@708: foozy@708: \subsection{\hook{pretxncommit}---before completing commit of new changeset} foozy@708: \label{sec:hook:pretxncommit} foozy@708: foozy@708: この制御フックは、 foozy@708: トランザクション--- foozy@708: このトランザクションは、 foozy@708: 新たなチェンジセットのコミットを管理します foozy@708: ---が完了する前に実行されます。 foozy@708: フックの実行が成功した場合、トランザクションは完了し、 foozy@708: チェンジセットがリポジトリにおいて永続化されます。 foozy@708: フックの実行が失敗した場合、 foozy@708: トランザクションは巻き戻され、 foozy@708: コミットに関するデータは破棄されます。 foozy@708: foozy@708: このフックは、 foozy@708: 「ほぼ新規作成された」チェンジセットに関するメタデータにアクセスできますが、 foozy@708: 永続化されるような操作をこれらのデータに基づいて行うべきではありません foozy@708: 作業ディレクトリも変更すべきではありません。 foozy@708: foozy@708: このフックの実行中に、 foozy@708: 他の Mercurial プロセスが同じリポジトリにアクセスしてきた場合、 foozy@708: このプロセスからは、 foozy@708: 「ほぼ新規作成された」チェンジセットが永続化されたもののように見えます。 foozy@708: この状況を回避する手順を踏まないと、 foozy@708: 競合状態になりかねません。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{parent1}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットにとって、 foozy@708: 第1親となるチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{parent2}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットにとって、 foozy@708: 第2親となるチェンジセットのID。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{precommit} (\ref{sec:hook:precommit}~節) foozy@708: foozy@708: \subsection{\hook{preupdate}---before updating or merging working directory} foozy@708: \label{sec:hook:preupdate} foozy@708: foozy@708: この制御フックは、 foozy@708: 作業領域ディレクトリにおける \hgcmd{update} ないし \hgcmd{merge} foozy@708: の実施前に実行されます。 foozy@708: このフックは、 foozy@708: Mercurial の \hgcmd{update} foozy@708: 実施前確認が \hgcmd{update} ないし \hgcmd{merge} foozy@708: を実行可能と判断した場合にしか実行されません。 foozy@708: フックの実行が成功した場合、 foozy@708: \hgcmd{update} ないし \hgcmd{merge} の実行は継続されますが、 foozy@708: フックの実行が失敗した場合、 foozy@708: \hgcmd{update} ないし \hgcmd{merge} は実行されません。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{parent1}] チェンジセットID。 foozy@708: 作業領域ディレクトリが \hgcmd{update} される親チェンジセットのID。 foozy@708: 作業領域ディレクトリが \hgcmd{merge} される場合は、 foozy@708: 現在の親チェンジセットと同じになります。 foozy@708: foozy@708: \item[\texttt{parent2}] チェンジセットID。 foozy@708: 作業領域ディレクトリが \hgcmd{merge} される場合にのみ設定されます。 foozy@708: 作業領域ディレクトリの \hgcmd{merge} 対象となるチェンジセットのID。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{update} (\ref{sec:hook:update}~節) foozy@708: foozy@708: \subsection{\hook{tag}---after tagging a changeset} foozy@708: \label{sec:hook:tag} foozy@708: foozy@708: このフックは、タグが生成された後で実行されます。 foozy@708: foozy@708: このフックに渡されるパラメータは: foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{local}] 真偽値。 foozy@708: タグがリポジトリに対してローカルなもの foozy@708: (\sfilename{.hg/localtags} に情報が格納される)なのか、 foozy@708: Mercurial に管理されるもの(\sfilename{.hgtags} に情報が格納) foozy@708: なのかを表します。 foozy@708: foozy@708: \item[\texttt{node}] チェンジセットID。 foozy@708: タグ付けされるチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{tag}] 文字列。 foozy@708: 作成されるタグの名前。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 生成されるタグが構成管理対象となる場合、 foozy@708: このフックの実行に先立って foozy@708: \hook{commit} フック(\ref{sec:hook:commit}~節)が実行されます。 foozy@708: foozy@708: 要別途参照: foozy@708: \hook{pretag} (\ref{sec:hook:pretag}~節) foozy@708: foozy@708: \subsection{\hook{update}---after updating or merging working directory} foozy@708: \label{sec:hook:update} foozy@708: foozy@708: このフックは、 foozy@708: 作業領域ディレクトリにおける \hgcmd{update} ないし \hgcmd{merge} foozy@708: が完了した際に実行されます。 foozy@708: \hgcmd{merge} は失敗し得る foozy@708: (外部コマンドの \command{hgmerge} foozy@708: が各ファイルにおける衝突の解消に失敗した場合)ので、 foozy@708: このフックには \hgcmd{update} ないし \hgcmd{merge} foozy@708: の成否が伝えられます。 foozy@708: foozy@708: \begin{description} foozy@708: \item[\texttt{error}] 真偽値。 foozy@708: \hgcmd{update} ないし \hgcmd{merge} 実行が成功したか否かを表します。 foozy@708: foozy@708: \item[\texttt{parent1}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットにとって、 foozy@708: 第1親となるチェンジセットのID。 foozy@708: foozy@708: \item[\texttt{parent2}] チェンジセットID。 foozy@708: 新しくコミットされたチェンジセットにとって、 foozy@708: 第2親となるチェンジセットのID。 foozy@708: foozy@708: \end{description} foozy@708: foozy@708: 要別途参照: foozy@708: \hook{preupdate} (\ref{sec:hook:preupdate}節) foozy@708: foozy@708: %%% Local Variables: foozy@708: %%% mode: latex foozy@708: %%% TeX-master: "00book" foozy@708: %%% End: