Mercurial は完全に非中央集約的なツールであるため、利用者相互の連携に関しては何ら制約を課すことをしません。ですが、分散構成管理に馴染みが無いのであれば、いくつかのツールや使用例を知っておくことは、妥当な作業手順のモデルを考える際に役に立ちま す。
Mercurial は、いくつかの有用な機能を提供する、強力なウェブインタフェースを持っています。
対話的な利用の場合、ウェブインタフェース経由で1つないし複数のリポジトリの閲覧ができます。リポジトリ履歴の参照や、個々 の変更(コミットメッセージや差分)の検証、および各ディレクトリやファイルの内容の参照、といったことができます。
通知に関しても、ウェブインタフェースは、リポジトリにおける変更に関する RSS 配信機能を提供します。お気に入りのツールを使ってリポジトリを “購読” することもできますし、リポジトリにおける活動状況の自動通知を即座に行うこともできます。リポジトリ提供者側における追加設定が不要であることから、筆者自身は、変更通知のメーリングリストよりも、「 RSS 配信を購読」するモデルの方が非常に便利だと思います。
ウェブインタフェースにより、遠隔ユーザによるリポジトリの複製や変更の取り込み、および(サーバ側でそれを許可しているならば)変更の受理が可能になります。 Mercurial の HTTP トンネリングプロトコルでは、積極的にデータの圧縮を行いますので、狭い帯域のネットワーク接続経由でも効率よく機能します。
ウェブインタフェースを触ってみる最も簡単な方法は、 Mercurial のマスタリポジトリであるhttp://www.selenic.com/repo/hg?style=gitwebのような、既存のリポジトリにウェブブラウザで接続してみることです。
自身でリポジトリのウェブインタフェースを提供することに興味がある場合、 Mercurial には2つの選択肢があります。1つは“hg serve” コマンドを使用するもので、短期間の “軽量な” 稼動の場合に最適です。このコマンドの利用に関する詳細は、6.4 節を参照してください。長期的且つ常時利用可能な稼動を望む場合は、 Mercurial に組み込まれている CGI (Common Gateway Interface)機能が、一般的な全てのウェブサーバで利用可能です。 CGI 設定の詳細は、6.6 節を参照してください。
適切な柔軟性を持つツールを使うことで、作業手順の決定は、技術的な問題から組織工学的(social engineering)な問題へと変わります。 Mercurial は、プロジェクトにおける作業手順の構成に関して殆ど制限を課さないため、個別の要望に沿ったモデルの設定と運用は利用者次第となります。
いずれのモデルにおいても心得ておくべき最も重要な点は、それを利用する人々の要望と能力にどれだけ適合するか、ということです。これは自明に見えるかもしれませんが、ほんの少しの間でもこのことを忘れてはいけません。
筆者は以前、完璧と思える作業手順モデルを構築したのですが、開発チームに少なからぬ量の驚きと不和をもたらしました。複雑なブランチ群が必要な理由と、それらの間における変更の取り扱いについて説明しようと試みました が、チームのメンバーの何人かが異を唱えてきたのです。彼らは聡明な人達でしたが、作業における制約に注意を払 う1 ことも、筆者が唱えるモデルの細部における制約の重要性に向き合おうともしませんでした。
近い将来の社会的・技術的な問題から目を背けないでください。どんな計画を実施しようとも、間違いや問題が発生した場合に備えるべきです。予想可能な問題に対して、自動的な防御や即時復旧のための仕組みの追加を考慮しましょう。例えば、リリース向けではな い変更のためのブランチを作成しようとした場合、他の作業者がリリース用ブランチにうっかりマージしてしまう可能性について、早い時点で考慮したほうが良いでしょう。不適切なブランチからチェンジセットをマージさせないフックを記述することで、この問題に関し ては回避可能です。
持続可能性の点から “何でもアリ” なやり方はお薦めしませんが、簡単に把握することができるモデルであり、いくつかの特異な状況で は非常に良く機能します。
一つの例として、多くのプロジェクトが、直接会うことの稀な弱くまとまった協力者グループを持ている As one example, many projects have a loose-knit group of collaborators who rarely physically meet each other. 時折の “全力疾走” (sprints)2 を 設けることで、距離によって隔てられた作業に打ち勝つグループもあります。全力疾走の機会では、多くの人が共に同じ場所(会社の会 議室やホテルの会議室の類)に集まり、数日程度を閉じこもって過ごし、少量のプロジェクトに集中してハッキングを行いま す。
全力疾走は、大掛かりなサーバインフラを必要としない“hg serve” コマンドを利用するのにちょうど良い機会です。以下の6.4 節 を読むことで、すぐにでも“hg serve” を使い始めることができます。そうしたなら、周囲の人達にサーバを実行中であることを伝 え、インスタントメッセンジャー等を使用して URL を送れば、共同作業する上での折り返し地点まで辿り着きました。ブラウザに 教えられた URL を入力すれば、彼らはすぐにでもあなたの変更をレビューすることができますし、あなたからバグ フィックスを入手してそれを検証したり、新機能が含まれるブランチを複製してそれを試してみたりすることができま す。
その場限りのこのような形式で事を進めることの利点と欠点は、あなたによる変更の存在と、どこでアクセス可能かを知る人だけ が、それを参照することができる、という点にあります。このような非公式な手法は、複数の異なるリポジトリからの取り込みが各自に 要求されるため、数人以上に対しては単純に規模の拡大ができません。
小規模なプロジェクトにおいて、中央集約的な構成管理ツールからの移行する最も簡単な方法は、単一の共有リポジトリを経由して変更 のやり取りをする、というものです。この体制は、より野心的な作業手順体系のための最も基本的な “構成要素” でもありま す。
開発者(contributor)は、共有リポジトリの複製を行うことで作業を開始します。必要な時にいつでも変更の取り込みを行えます し、開発者の何人かは(全員でも可)、外部に公開可能になった際に変更を共有リポジトリに反映させる権限を持ちま す。
このモデルであっても、共有リポジトリを経由せずにお互いの変更を直接“hg pull” することは、開発者にとっては意義のあるこ とです。例えば、暫定的なバグ修正を行ったものの、共有リポジトリにその修正を公開した場合に、その修正を取り込んだ他の開発者の 作業に支障をきたす恐れがある、という場合を考えてみましょう。バグ修正を含む自分のリポジトリから一時的なリポジトリを複製し、 複製先で修正内容を検証してもらえるように他の開発者にお願いすることで、潜在的な損害を低減することができます。このように することで、潜在的な危険性を持つ変更であっても、簡単な検証が済むまでは公開されないようにすることができま す。
この種のやり取りの場合は、共有リポジトリへの安全な変更反映のためにssh プロトコルを使用するのが一般的です(6.5 節参 照)。読み出し専用リポジトリを、 CGI を使用して HTTP 経由で公開することも可能です(6.6 節参照)。リポジトリへの変更反映 が必要ない場合や、リポジトリの履歴をウェブブラウザ経由で参照したい場合には、 HTTP 経由での公開で十分ニーズが満たされま す。
一定以上の規模を持つプロジェクトにおいては、作業の進展が同時に複数の「前線」で行われることは自然な成り行きです。ソフトウェ ア開発の場合、どのプロジェクトでも、一定期間ごとに公式リリースを行うのが一般的です。各リリースは最初の公開の後に、一定期間 の “保守状態” (maintenance mode)となることがあります。保守リリースではバグ修正のみを扱い、新規機能については取り扱 わないのが通例です。これら保守リリースと平行して、(場合によっては複数の)将来のリリースに向けた開発が進 行します。方向性の少し異なる、これら進行中の個々の開発を指すのに、一般的に “ブランチ” という表現を使いま す。
Mercurial は特に、複数の異なるブランチを同時に管理することに適しています。それぞれの “開発指向” ごとに、別々の共有用リ ポジトリを用意することで、必要になる都度、あるリポジトリから別のリポジトリへのマージを行えば良いのです。各リポジトリは互い に独立していますから、誰かが明示的にマージしない限りは開発ブランチにおける不安定な変更が、安定版のためのブランチに影響を与 えることはありません。
ブランチごとにリポジトリを用意する遣り方の実際の例を以下に示します。中央のサーバに “メインブランチ” があるものとします。
開発者はメインブランチから複製し、変更、変更のテスト、コミットの後に、変更をメインブランチのリポジトリに反映しま す。
メインブランチがリリースのマイルストーンに達したならば、マイルストーンとなるリビジョンに“hg tag” コマンドで永続的な名 前を付与します。
メインブランチでは開発が継続しているとします。
リリースマイルストーン後の任意の時点でリポジトリを複製した開発者は、リリースマイルストーンで記録されたタグを使うこと で、タグが付与されたリビジョンがコミットされた時点と厳密に一致する作業領域ディレクトリを“hg update” コマンドにより複製す ることができます。
それに加えて、メインブランチでのタグ付けの後で、サーバ上のメインブランチを、新たな “安定版” ブランチ(のリポジトリ)へと複製する こともできます3 。
安定版ブランチに対して変更する必要がある場合、開発者は安定版ブランチのリポジトリから複製し、変更、変更のテスト、コミッ トの後に、変更を安定版ブランチのリポジトリに反映します。
Mercurial のリポジトリはお互いに(物理的に)独立しており、リポジトリ間での変更の自動的なやり取りは行われないため、安定 版ブランチととメインブランはお互いに隔離されています。メインブランチに加えた変更が安定版ブランチに “漏れ出す” ことはありま せんし、その逆に関しても同様です。
安定版ブランチにおける全てのバグ修正を、メインブランチに反映したい場合もあるでしょう。メインブランチでバグ修正を再度 (手動で)行う代わりに、安定版ブランチから取り込んだ変更をメインブランに対してマージすることで、安定版ブランチにおける変更 をメインブランチに持ち込むことができます。
この時点でのメインブランチは、安定版ブランチには無い変更を保持していますが、安定版ブランチにおける全てのバグ修正を保持しています。安定版ブランチは、メインブランチにのみ含まれる変更には影響を受けないままで す。
大規模プロジェクトで有効な変更管理方法は、開発チームを小さなグループに分割することです。プロジェクト全体が参照する単一の “マスター” ブランチから複製した共有ブランチ(= リポジトリ)を、各グループごとにそれぞれ持ちます。個々のブランチ上で作業す る開発メンバーは、他のブランチにおける開発作業とは隔離されています。
とある機能が適切な状況4 に 到達したと判断されたなら、当該機能の担当チームでは、マスターブランチ(のリポジトリ)から反映した変更を自チームのブランチ (のリポジトリ)へとマージしてから、マスターブランチへとマージ結果を反映すれば良いのです。
プロジェクトによっては、 “train” モデルで運用されている場合もあります。 “train” モデルで運用さ れているプロジェクトでは、リリースは数ヶ月ごとに設定されており、 “train” が出発準備完了した段 階5 で提供 可能な機能だけがリリースに含まれます。
このモデルは、先に説明した機能別ブランチによる作業と似ています。 “train” モデルの場合、機能別ブランチが列車に乗りそこ なった場合、当該機能の担当チームでは、自チームの機能ブランチ(リポジトリ)に対して、リリース列車に含まれる変更の取り込みお よびマージを行い、マージ結果に対して作業を継続する必要がある点が異なります。このマージ作業を行うことで、次回リリースの際 に、当該機能が整合性を保つことができます。
Linux カーネルの開発体制は、浅い階層構造と、それを取り囲む一見混沌とした群集から成り立っています。殆どの Linux 開発者が、 Mercurial と同等の機能を持った分散構成管理ツールであるgit コマンドを使用しているので、 Linux カーネル開発における作業手順 の説明は Mercurial 利用にとっても有用性を持っています。気に入ったアイデアがあれば、ツールを超えて手法を利用することは可能 なのですから。
コミュニティの中心には、 Linux を創り出した Linus Torvalds 氏がいます。彼は単一のソースリポジトリを公開しており、開発コ ミュニティ全体にとっては、このリポジトリが “権威ある” 現行ソースツリーとみなされます。誰もが Torvalds 氏のソースツリーを 複製できますが、誰のツリーから変更を取り込むかという点に関して、 Torvalds 氏は非常に慎重な選択をしていま す。
Torvalds 氏には “信頼できる補佐役” が何人かいます。彼ら補佐役が公開している変更は、レビューが行われていなくても、大概は Torvalds 氏により取り込まれます。補佐役のうちの何人かは、 “保守担当者” として承認されており、カーネルの特定のサブシステムに 関する責任を負っていますとあるカーネルハッカーがサブシステムへの変更を行い、その変更を最終的に Torvalds 氏のツリーに取り込 んで欲しいと考えた場合、当該サブシステムの保守担当者が誰であるかを調べて、その担当者に変更の採用をお願いする必要があ ります。保守担当者が変更のレビューの後に採用に同意した場合、その変更は手順に従い Torvalds 氏へと渡されま す。
個々の補佐役は、変更のレビュー・承認および公開に関するそれぞれの手法を持っており、 Torvalds 氏への変更送付時期の判断に 関しても、それは当てはまります。それに加えて、異なる目的向けの良く知られたブランチがいくつか存在します。例えば、古い版の カーネルの “安定版” リポジトリが、必要に応じて深刻な障害の修正を適用するために、少数の人々により保守されています。何人かの 保守担当者は、複数のソースツリーを公開しています。1つは実験的な変更のためのもの、1つは上流リポジトリから配布 しようとしている変更のためのもの、といった按配です。他の保守担当者は、ソースツリーを1つだけ公開していま す。
Linux におけるこのモデルは、2つの注目に値する特徴を持っています。1つ目は “取り込み限定” (pull only)である点です。保 守担当者以外が変更を反映できるソースツリーが殆ど無く、他の人が管理しているソースツリーに変更を反映する方 法が無いことから、変更を反映させたいソースツリーの保守担当者に対して、変更の採用をお願いする必要がありま す。
2つ目の特徴は、知名度と評判に基づいている点です。名の知られていない開発者からの変更依頼の場合、 Torvalds 氏が依頼メー ルを受け取ったのなら、返信もせずに無視してしまうでしょう。しかし、サブシステムの保守担当者が依頼メールを受け取った場合、内 容がレビューされた上で、それが保守担当者の基準を満たしていれば、おそらくその変更は採用されるでしょう。より “良い” 変更 で貢献する程、保守担当者はあなたの判断を信頼するでしょうし、あなたの変更依頼が受理度される度合いも増すで しょう。あなたが有名になり、 Torvalds 氏がまだ受理していない息の長いブランチの保守を行うようになれば、あ なたの作業内容に追従するために、似たような興味を持つ人々があなたの変更を定期的に取り込むようになるでしょ う。
知名度や評判は、必ずしもサブシステムや “人的” 境界を越えるわけではありません。専らストレージ系で著名なハッカーが、ネッ トワークのバグ修正を試みた場合、ネットワークサブシステムの保守担当者による監査は、全くの部外者による変更と同程度となるで しょう。
より整然としたプロジェクト従事の経験を持つ人にとって、相当に無秩序な Linux カーネルの開発手順は、全く非常識なものに見えることでしょう。この開発形態は、個人の気まぐれの影響を受けやすいのです。作業は各自の都合の良い 時に、驚くべきペース行われます。それでもなお Linux は、成功を収めた重要なソフトウェアの1つとなっていま す。
他の人のリポジトリからは変更の反映のみしかしないモデルと、複数の人々が共有リポジトリへの変更反映を行うことができる開発モデ ルの、どちらが “より良い” モデルであるかは、オープンソースコミュニティにおいて継続的な議論の的になっています。で す。
共有リポジトリ+反映モデルの支持者は、その手法を積極的に使用するツールを使用する傾向にあります。 Subversion のような中 央集約的な構成管理ツールを使用している場合、採用するモデルの選択肢はありません。共有リポジトリ+反映モデルがツールによって 強制されるため、他のモデルを使用するには、そのツール上で独自の手法(例えば、手動でpatchを宛てる、など)を駆使する必要が あります。
Mercurial のような適切な分散構成管理ツールであれば、両方のモデルを選択可能です。利用者間の連携形態は、ツールにより強制 される歪んだものではなく、固有の要望や好みに基づいて構築することができます。
共有リポジトリを構築し、各作業者が手元のリポジトリと共有リポジトリとの間で、変更の伝播を開始し始めたなら、チーム内の開発の 方向性を同時に複数管理するという、連携に関することではありつつも、微妙に異なる難問に直面することでしょう。この問題は開発 チームの連携方式と密接に関連してはいるものの、改めて取り上げる価値があるほど非常に込み入った話であることから、8 章で改め て説明します。
本章の残りは、共同作業者に対してデータの提供を行う上での問題点に割きたいと思います。
Mercurial の“hg serve” コマンドは、小さく緊密で足並みの早い集団での利用に大変適しています。“hg serve” コ マンドはまた、ネットワーク越しでの Mercurial コマンドの利用感を掴むための、素晴らしい手段を提供していま す。
リポジトリ配下において“hg serve” を実行することで、1秒も経たずに特製の HTTP サーバが起動します。実行が停止されるま での間にこの HTTP サーバは、任意のクライアントからの接続を受理し、当該リポジトリ中のデータの提供を行います。たった今 起動したばかりのサーバの URL を知っていて、ネットワーク越しにサーバが稼動しているコンピュータと通信でき るなら、ウェブブラウザや Mercurial を利用して、誰もがリポジトリからデータを読み出すことができます。ノー ト PC 上で稼動する“hg serve” プロセスの URL は、http://my-notepc.local:8000/ のような形式になりま す。
“hg serve” コマンドは汎用ウェブサーバではありません。このコマンドを使用することで2つの事が可能になりま す。
とりわけ遠隔ユーザによる対象リポジトリの変更を許可しないことから、“hg serve” は読み出し専用としての利用が想定されてい ます。
Mercurial を既に利用し始めているのであれば、自身のコンピュータ上のリポジトリを対象として“hg serve” を利用することがで きますから、ネットワーク越しに公開されているリポジトリの場合と同様に、“hg clone” や“hg incoming” のような コマンドを使用して、“hg serve” によって起動されたサーバと通信してみましょう。ネットワーク経由で公開され ているリポジトリに対するコマンドの使用方法を、手早く習得する一助に“hg serve” を使用するのも良いでしょ う。
“hg serve” は、ネットワーク越しの読み出し操作を認証無しで全て許可しているため、対象リポジトリからデータを読み出すために誰 が接続して来るのかを、気にしなくて良い(あるいは完全に制御できる)環境でのみ“hg serve” を使うようにすべきで す。
コンピュータやネットワークへのファイヤウォールの導入状況について、“hg serve” コマンドは一切関知しません。ファイヤ ウォールの検出も制御もできません。実行中の“hg serve” プロセスとの通信ができない場合は、(理商社が正しい URL を使用して いることを確認した後で)ファイアウォールの設定を確認すべきです。
“hg serve” によるネットワーク接続の受け付けは、通常は 8000 番ポートで行われます。当該ポートが既に他のプロセス により使用されていた場合は、-p オプションを使用することで、接続受け付けポート番号を指定することができま す。
“hg serve” 起動の際には通常何も出力されませんので、少々不安になるかもしれません。“hg serve” が適切に稼動していること を確認したり、共同作業者に送付する URL を知りたいのであれば、-v オプション付きで“hg serve” を起動してくださ い。
Secure Shell (ssh)プロトコルを使用することで、ネットワーク接続越しに安全に変更内容の取り込み・反映を行うこと ができます。この接続方法を正しく機能させるには、クライアントあるいはサーバ側で少々設定が必要かもしれませ ん。
ssh に馴染みがないのであれば、他のコンピュータと安全に通信するためのネットワークプロトコルである、と理解しておいてくだ さい。 Mercurial で ssh を利用するには、サーバへのログインおよびコマンド実行ができるように、サーバ側にユーザアカウントを (必要であれば複数)用意する必要があります。
(ssh について詳しい場合、以降の説明はおそらく非常に初歩的に感じるでしょう)
ssh プロトコルを利用する場合の URL は、概ね以下のような形式を持ちます。
ssh プロトコルにおける URL 表記のパス要素部分には、値の解釈に関する標準的な手法がないために、混乱の余地 が多々あります。一群のプログラムは、パス要素部分に関して他のプログラムと異なる振る舞いをします。このよう な状況は理想的ではありませんが、状況が変わりそうにはありません。ですから以降の説明は注意深く読んでくださ い。
Mercurial はパス部分を、サーバにログインするユーザの、ホームディレクトリに対する相対パスとみなします。例えば、サーバに おける foo ユーザのホームディレクトリが/home/foo である場合、 ssh プロトコルにおける URL のパス要素が bar であれば、その URL により実際に参照されるのは/home/foo/bar ディレクトリです。
他のユーザのホームディレクトリに対する相対パスを指定する場合は、チルダ文字( )にユーザ名(ここではotheruser としま す)を続けたパスで始まる、以下のような表記になります。
絶対パスによる指定を行う場合は、以下のようにパス要素をダブルスラッシュで始めます。
殆ど全ての Unix ライクなシステムには OpenSSH が事前導入されています。 Unix ライクなシステムを使用している場 合、which ssh と入力することでssh コマンド(通常は /usr/bin にインストールされています)のインストールの有無を確認するこ とができます。予想に反してインストールされていなかった場合には、システム添付のドキュメントを参照してインストール方法を調べ てください。
Windows の場合、妥当な ssh クライアントを選択してダウンロードする必要があります。主な選択肢は2つありま す。
どちらの場合でも、 Mercurial が ssh クライアントコマンドを探し出せるようにMercurial.ini ファイルを編集する必要があるでしょう。例えば PuTTY を使用するなら、コマンド行で実行する ssh クライアントとしてplink を実行することになります。
ssh クライアントを使用する度に、毎回パスワード入力を繰り返さなくても良い様に、鍵対(key pair)6 を生成することをおすすめし ます。 Unix ライクなシステム7 で は、ssh-keygen コマンドで鍵対を生成します。 Windows 上で PuTTY を使用している場合は、puttygen コマンドで鍵対を生成し ます。
鍵対を生成する場合、パスフレーズで鍵を守るようにするのが、一般には非常に賢明とされています(ssh プロトコルによる安全な ネットワークを、自動化された処理において使用する場合を除く)。
しかし、単に鍵対を生成しただけでは不十分です。ネットワーク経由でログインするサーバ側アカウントにおい て、承認鍵一覧に公開鍵を追加登録する必要があります。 OpenSSH が導入されているサーバでの公開鍵の追加は、 当該アカウントの.ssh ディレクトリ配下のauthorized_keysファイルに公開鍵の内容を追加することで行われま す。
Unix ライク名システムでは、公開鍵は通常 .pub 拡張子を持っています。 Windows 上でputtygen を使用する場合は、任意の ファイル名で保存可能ですし、公開鍵の内容が表示されているウィンドウからauthorized_keys へ直接貼り付け(paste)ることも可 能です
認証エージェントは、パスフレーズをメモリ上に格納するデーモンプロセスです(そのため、ログアウト後に再度ログインした場合、パ スフレーズは失われます)。認証エージェントの稼動を検知すると、 ssh クライアントは認証エージェントにパスフ レーズの問い合わせを行います。認証エージェントが稼動していないか、あるいは必要なパスフレーズを記憶してい ない場合は、 Mercurial によるサーバ連携(例: “hg push” や“hg pull”)の都度、パスフレーズの入力が必要で す。
認証エージェントによるパスフレーズ保存の欠点は、入念に準備した攻撃者にとっては、たとえ定期的に再起動しているシステムで あっても XXXXXX power-cycled XXXX パスフレーズの平分を復元可能である点です。この問題が許容可能なものか否かは、各自で 判断する必要があります。認証エージェントを使用することで、繰り返しパスフレーズを入力する手間を大幅に低減することができま す。
Unix ライク名システムでは、認証エージェントはssh-agent という名前で、ssh-addコマンドを使ってエージェントの記憶領域 にパスフレーズを保存します。 Windows 上で PuTTY を使用する場合は、pageant コマンドが認証エージェントして振舞いま す。システムトレイに追加されたアイコンをクリックすることで、格納されたパスフレーズの管理を行うことができま す。
初心者にとって ssh の設定は面倒なので、問題が発生する状況も多岐に渡ります。 Add Mercurial on top, and there’s plenty more scope for head-scratching. XXXXX 問題発生の可能性は、クライアント側ではなくサーバ側の方が高いです。ありがたいことに、一旦正しく動作する設定ができてしまえば、通常は無期限に正しく動作し続けます。
Mercurial で ssh サーバと通信をしてみる前に、通常のssh ないしputty コマンドによるサーバとの通信を確認するのが無難で す。直接コマンドを使用した際に問題が発生したならば、 Mercurial が機能しないことは確実です。更に悪いことに、 Mercurial を 介しての ssh サーバとの連携は、根本的な原因が隠れてしまいます。 ssh に関連する Mercurial の問題を解決する 場合は、 Mercurial の不具合を疑う前に、 ssh クライアントコマンドの直接実行が機能することを確認してくださ い。
サーバ側で最初に確認すべき事は、あるマシンからサーバマシンへの実際のログインの可否です。ssh ないしputty でログインで きない場合、表示されるエラーメッセージから問題特定のヒントが得られるかもしれません。よくある問題には以下のようなものがあり ます。
これまでの話をまとめると、サーバマシン上の ssh サーバプロセスとの通信に問題がある場合、まずはサーバプロセ スの稼動状況を確認してください。多くのシステムでは、 ssh 自体はインストールされていますが、初期状態では無 効化されている場合があります。この確認が済んだなら、次に確認するのは、 ssh サーバプロセスが外部からの接続 を受け付けるポート(通常は 22 番)に対する外部からの接続を、サーバのファイヤーウォール設定が許可している か否かです。これら2つの確認を済ませるまでは、突拍子もない設定ミスの可能性に関して心配する必要はありませ ん。
秘密鍵用パスフレーズの保持のために、クライアント側で認証エージェントを使用している場合は、パスフレーズやパスワードの問 い合わせを受ける事無く、サーバにログインできていなければなりません。パスフレーズを問い合わせるプロンプトが表示される場合、 問題の可能性のあるものが幾つかあります。
サーバ側ユーザのパスワードの問い合わせがあった場合、別な問題の可能性を検討する必要があります。
以下のコマンド実行に対して、(サーバ側の)現在時刻を表示する1行だけが出力される、という状態が理想的です。
上記のような非対話的なコマンド実行の場合にも、バナー表示やそれに類する表示が行われる ような設定が、連携先サーバ側で行われている場合には、この先の手順に進む前に、対話的な実 行8 の時に のみ、これらが表示されるように設定変更してください。これを怠ると、バナー等の表示が Mercurial の出力を混乱させてし まいます。更に問題なことに、バナー等の表示は Mercurial コマンドの遠隔実行における潜在的な問題と成り得ま す。非対話的なssh 連携において、 Mercurial は極力バナー等の表示の検知ならびに無視に努めますが、必ずしも全 てが無視できるわけではありません(サーバ側でログイン時実行スクリプトをカスタマイズする場合、tty -s コマ ンドの戻り値を判定することで、当該スクリプトが現在対話シェルで実行されているか否かを判定することができま す)9 。
素の ssh によるサーバ連携が機能することを確認したならば、次に確認するのは、サーバ側での Mercurial 実行の可否です。以下の コマンド実行が正しく機能することを確認してください。
通常の“hg version” 出力ではなくエラーメッセージが表示される場合、大概は /usr/bin に Mercurial がインストールされてい ないことが原因です。その場合でも、必ずしも /usr/bin にインストールする必要はありません。しかし、考え得る以下の幾つかの原 因に関して確認が必要です。
ssh 経由での“hg version” コマンド実行が成功したなら準備は完了です。サーバ・クライアントは共に問題解決済みとなりまし た。サーバ上で公開されているリポジトリに、当該ユーザ名による Mercurial でのアクセスが可能になっている筈です。ここまでの確 認をクリアした上で、 Mercurial と ssh の連携において問題が発生した場合、問題発生の状況をより明確にするために、--debug オプ ションを付けての実行を試してみてください。
ssh プロトコルを使用する場合、 ssh プロトコル自身が通信時にデータ圧縮を行うため、 Mercurial は圧縮を行いません。しかし、 ssh クライアントの(通常の)基底動作では、圧縮を行いません。
高速な LAN の場合を除けば(無線ネットワークであっても)、通信時の圧縮は Mercurial のネットワーク経由の処理を顕著に高速 化します。例えば WAN 経由での連携の場合、かなり大きなリポジトリの複製に要する時間が 51 分から 17 分に低減した、との性能計 測報告もあります。
ssh とplink の両方とも、通信時圧縮を有効化する-C オプションを受け付けます。hgrc ファイルを以下のように編集すること で、 ssh プロトコル利用の際に常に圧縮を行うように Mercurial に対して指定できます。
ssh を使用している場合は、連携先サーバとの通信の際には常に圧縮を行うように設定することもできます。この設定を行う には、ホームディレクトリ配下の.ssh/config ファイル(無い場合は新規に作成します)に以下のように記述しま す。
上記の記述は、hg という別名(alias)を作成します。ssh 実行の際のコマンド行記述や、 Mercurial の ssh プロトコルにおける URL として、hg を(ホスト名として)使用した場合、ssh は通信時圧縮を行いつつ hg.example.com に接続します。この設定によ り、入力の便利な省略名と、圧縮指定の両方を手にすることができます。
意気込み次第では、 Mercurial の CGI インタフェースの設定は、数分のものを数時間にしてしまう可能性がありま す。
最も単純な例から初めて、より複雑な設定へと向けて進めてゆきましょう。最も基本的なケースですら、ウェブサーバの設定ファウ ルの読み書きを行う必要が出てくることでしょう。
読み進める前に、システムの設定状況に関する幾つかの確認を行いましょう。
ウェブサーバがインストールされていない場合や、 Apache ウェブサーバの設定経験があまり無い場合には、 Apache ウェブサーバ の代わりにlighttpd ウェブサーバの利用をお薦めします。 Apache ウェブサーバの設定は、凝っていて且つわかりにくいという評判に 見合うものがあります。lighttpd は Apache ウェブサーバ程の機能は無いものの、足りない機能の殆どが Mercurial リポジトリの運 用には関係ないものです。それに加えて、明らかに lighttpd は Apache ウェブサーバよりも簡単に利用が開始できま す。
Unix 的なシステムを利用している場合、ウェブページとして公開するためのpublic_html のようなディレクトリを、ホー ムディレクトリ配下に持つのが共通認識となっています。このディレクトリ直下に置いたfoo という名前のファイル は、http://www.example.com/ũsername/foo という URL で参照可能になります。
設定を始めるに当たって、 Mercurial のインストール先に格納されているhgweb.cgi スクリプトの所在を 確認してください。システム上の所在がすぐにはわからなかった場合は、 Mercurial のマスターリポジトリか らhttp://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgiを直接ダウンロードしてください。
上記スクリプトをpublic_html 配下に配置し、実行可能となるように権限設定を行います。
chmod コマンドへの 755 引数指定は、スクリプトに実行可能権限を付与する以上の付加的な指定を意味します。この設定により、 スクリプトが誰からも実行可能になると同時に、 “group” および “other” による書き込み権限が剥奪されます。これらの書き込み権限 を有効なままにした場合、 Apache の suexec サブシステムは、おそらくスクリプトの実行を拒否するでしょう。実のところ suexec は、スクリプトが配置されているディレクトリに対する “group” および “other” による書き込み権限が剥奪されていることも要求しま す。
CGI を配置したならば、ウェブブラウザを起動してhttp://myhostname/∼myuser/hgweb.cgi に相当する URL にアクセスしてみま しょう。但し、ちょっとした失敗には身構えておいてください。所望の URL へのアクセスが失敗する公算は非常に高く、その理由は多 岐に渡ります。実際のところ、以下の起こり得るエラー要因の全てで躓く可能性がありますから、この先は注意深く読み 進めてください。以下で述べる問題は、まっさらな状態からインストールした Apache を使い、この実例を行うた めに新たに生成したユーザアカウントで、 Fedora 7 上で作業を実施した際に、筆者が実際に直面した全ての問題で す。
使用しているウェブサーバは、ユーザ毎のディレクトリを無効化しているかもしれません。 Apache を使用している場合は、設定 ファイル中に UserDir 指定の有無を確認してください。この指定が無い場合、ユーザ毎ディレクトリは無効になります。指定が有って も無効化されている場合も、ユーザ毎ディレクトリは無効になります。有効な UserDir 指定がある場合、UserDir 指定で記述されてい る文字列(例えば public_html)が、ホームディレクトリ直下で Apache が参照するサブディレクトリ名になりま す。
ファイルのアクセス権限が厳しすぎる可能性もあります。ウェブサーバは、対象となるユーザのホームディレクトリ、および public_html配下のファイル・ディレクトリの読み込みができなければなりません。適切な権限設定を行うための簡単な手順を以下に示します。
権限設定に関する他の要因の可能性がある場合は、ブラウザでの所望の URL アクセス時に、完全に空の画面が表示されることで しょう。この場合は、おそらくアクセス権限が緩すぎるのでしょう。例えば Apache の suexec サブシステムは、 group ないし other に書き込み権限が付与されたスクリプトは実行しません。
使用しているウェブサーバが、ユーザ毎ディレクトリ配下の CGI プログラムの実行を、禁止するように設定されて いる可能性も有ります。筆者の Fedora 7 システムにおける Apache の、初期状態のユーザ毎設定を以下に示しま す。
対象となる Apache 設定ファイル中に似たようなDirectory 設定がある場合、Options 指定に注目してください。ExecCGI が指定 されていない場合は一覧末尾にこれを追加し、ウェブサーバを再起動してください。
Apache が CGI を実行するのではなく、 CGI スクリプトの内容そのものを返却してきた場合は、以下の記述を(既に記述があるな らば)有効化するなり追加するなりしてください。
次に問題の発生し得るケースでは、 Python のバックトレースが表示され、mercurial 関連モジュールがインポート(import)で きない旨を伝えていることでしょう。所望の結果は得られていませんが、ウェブサーバは CGI スクリプトの実行を行うようになったの で、先程の状態からは前進しています!インポートができない旨のエラーは、システムワイドで利用可能な Mercurial ではなく、おそ らく個人的にインストールした Mercurial を実行している場合にのみ発生します。ウェブサーバが CGI プログラムを実行する場 合、各個人の対話的ログインセッションで実施されている環境変数指定が無い、ということを忘れないでください。 このエラーが発生した場合は、PYTHONPATH 環境変数設定が適切になるようにhgweb.cgi の記述を編集してくださ い。
最終的に、/path/to/repository が見つからない旨を伝える Python のバックトレースが確実に表示されることでしょ う。hgweb.cgi スクリプトを編集して、文字列 /path/to/repositoryを実際に公開したいリポジトリへの絶対パスで置き換えてくだ さい。
ここまで来れば、ウェブブラウザでページをリロードした際に、綺麗に HTML で整形されたリポジトリ履歴の表示を見ることがで きる筈です。お疲れ様です。
徹底的に実験するために、これまで Apache に関して説明したのと同様に、近年人気が高まっている lighttpd ウェブサーバで、同じリポジトリを公開するための設定記述に挑戦してみました。 Apache についてこれまで概説してきた全ての問題は既に克服済みですし、その殆どはウェブサーバ実装に依存しません。結果として、ファイル・ディレク トリの権限設定が妥当であることと、hgweb.cgi スクリプトが適切に改変済みであることは、ある程度確信できま す。
一旦 Apache での公開に成功していれば、lighttpd でのリポジトリ公開は簡単(言い換えるなら、lighttpd を使用する場合で も、前述の Apache に関する説明を読むべきと言えます)です。初期状態でmod_cgi および mod_userdir が無効化されていた場合、 これらを有効化するために、まずは、設定ファイルの mod_access セクションを編集する必要があります。その後、これらのモジュー ルを設定するために、設定ファイル末尾に数行ほど追加します。
この記述により、lighttpd はユーザ毎のディレクトリおよび CGI を認識します。 Apache よりも前にlighttpd の設定をしたと したら、殆ど間違いなく、 Apache の設定の際に経験したのと同じシステムレベルの設定ミスを犯したことでしょう。しかし Apache の使用経験が10年以上あり、且つ初めての lighttpd 使用ではあるものの、 Apache の設定よりも lighttpd のそれは著しく容易で あると思われます。
単一のリポジトリのみしか公開できないというのは、hgweb.cgi スクリプトの悩ましい制約です。同じスクリプ ト11 を異 なる名前で複製する、という面倒な方法よりは、hgwebdir.cgi スクリプトの使用がお薦めです。
hgwebdir.cgi の設定手順は、hgweb.cgi よりも多少込み入っています。まず始めにスクリプトのコピーを入手します。手近に無 い場合は Mercurial のマスターリポジトリからhttp://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgiを直接ダウン ロードしてください。
public_html 配下に上記スクリプトを配置し、実行可能となるように権限設定を行います。
基本的な設定が済んだなら、ブラウザでhttp://myhostname/∼myuser/hgwebdir.cgiにアクセスしてみましょう。空のリポジ トリリストが表示される筈です。何も表示されないか、エラーメッセージが表示される場合は、6.6.2 節で説明した潜在的問題一覧を一 通り確認してください。
hgwebdir.cgi スクリプトは外部設定ファイルを必要とします。基底状態のhgwebdir.cgi スクリプトは、自身と同じディレクトリ に格納されたhgweb.config ファイルを読み込もうとします。このファイルを生成し、誰に対しても読み出し権限を付与しなければな りません。このファイルの記述形式は、 Windows における “ini” ファイルのそれと同じで、 Python のConfigParser [Pyt]により解 析可能な形式です。
最も簡単にhgwebdir.cgi を設定するには、collections という名前のセクションを設定してください。このセクションを記述す ることで、名付けたディレクトリ配下の全てのリポジトリを自動的に公開します。このセクションの記述は以下のようになりま す。
Mercurial はこの記述を解釈するに当たり、 “=” 記号の右辺に記述されたディレクトリ階層下でリポジトリを探し、 “=” 記号の左 辺のテキストに合致する部分を、ウェブインタフェースでの一覧表示で実際に公開される名前から除外します。除外処理の後に残ったパ ス要素は、 “仮想パス” と呼ばれます。
例として /my/root/this/repo にリポジトリがあるとした場合、 CGI スクリプトは冒頭の/my/root 部分を名前から除外し、仮想パスとして this/repo を持つリポジトリとして公開します。 CGI スクリプトの基底 URL をhttp://myhostname/∼myuser/hgwebdir.cgi とすると、このリポジトリの完全な URL は、http://myhostname/∼myuser/hgwebdir.cgi/this/repo となります。
この設定記述例での左辺を /my/root から/my に変更した場合、hgwebdir.cgi はリポジトリ名から/my のみをzy歩外するの で、仮想パスは this/repo ではなくroot/this/repo となります。
hgwebdir.cgi は、設定ファイル中の collectionsセクションで列挙された個々のディレクトリに対して、再帰的にリポジトリを 探しますが、見つかったリポジトリから更に下への再帰的探索は行いません。
collections の機構は、多くのリポジトリを “fire and forget” 作法で公開するのに適しています。 CGI や設定ファイルの記述は 一度で事足ります。設定が済んだなら、hgwebdir.cgiに探索を指示したディレクトリ階層配下との間でリポジトリの移動を行うだけ で、リポジトリの公開・非公開を任意の時点で行うことができます。
hgwebdir.cgi スクリプトはcollections による公開の仕組みに加えて、特定の一覧指定によるリポジトリ公開をすることもで きます。この方法での公開をするには、以下のような形式の内容を持つpaths セクションを記述する必要がありま す。
上記の例では、個々の定義の左辺が仮想パス(URL 中に現れるパス要素)、右辺がリポジトリへのパスとなります。仮想パスの指 定と、ファイルシステム上のリポジトリ位置には、何の関連性も無い点に注意してください。
単一の設定ファイル中でcollections とpaths の両方を同時に使用することも可能です。
Mercurial のウェブインタフェース経由で、任意のリビジョンのアーカイブをダウンロードすることが可能です。このアーカイブには、 当該リビジョンにおける作業領域ディレクトリのスナップショットが格納されますが、リポジトリデータ部分は含まれませ ん。
この機能は既定状態では無効化されています。この機能を有効化するには、allow_archive 項目をhgrcファイルの[web] セクションに追加 してください12 。
Mercurial のウェブインタフェース(“hg serve” コマンドおよびhgweb.cgi ないしhgwebdir.cgi スクリプト)には変更可能な設定 項目が多数あります。これらの設定項目は[web] セクションに属しています。
値を指定しなかったり、allow_archive 項目そのものを指定しなかった場合、アーカイブダウンロード機能は無効化されます。 利用可能な全てのアーカイブ形式を有効化する記述例を以下に示します。
hgwebdir.cgi を使用する場合、幾つかの設定項目に関しては利便性上、hgrcファイルに記述する代わりに、hgweb.config ファ イルの[web] セクションに記述することができます。記述可能な設定項目は、motd およびstyle です。
ユーザ毎ないし大域的なhgrcファイルではなく、リポジトリ毎の.hg/hgrc で記述すべき[web] セクションの設定項目が幾つかあり ます。
hgrcファイルの[web] セクションにおける設定項目の幾つかは、“hg serve” コマンド専用の項目です。
Apache や lighttpd のようなウェブサーバは、リポジトリ所有者とは異なるユーザ権限で稼動する可能性がある、という点は重要で すので忘れないようにしてください。ウェブサーバによって起動されるhgweb.cgi のような CGI スクリプトは通常、ウェブサーバと 同一のユーザ権限で稼動します。
個人のhgrcファイルに[web] セクションを記述しても、 CGI スクリプトはその設定を読み込みません。個人のhgrcファイル に記述した設定は、当該ユーザ自身で“hg serve” コマンドを実行した場合にのみ効力を発揮します。 CGI スクリ プトの挙動に所望の設定を反映するには、ウェブサーバが稼動される際のユーザのホームディレクトリにhgrcファ イルを作成して所望の設定を記述するか、あるいはシステムワイドなhgrcファイルに所望の設定を追加してくださ い。