「入門TortoiseHg+Mercurial」発売中(詳細は「執筆情報」参照)


Emacs からの利用

本ページでは、 Emacs 用の Mercurial 連携フロントエンドとして提供される hg モード (mercurial.el)および mq モード(mq.el) に関する情報をまとめてみました。

備考: 本ページに記載されているコードは我流によるものですので、 Emacs lisp 界隈における、より一般的な実装方法に関して、 ご存知の方は御教頂けると幸いです。

なお、hg モードでは Emacs 21.x 以降で新設された関数が利用されているため、 実際に利用する環境で emacs-major-version 変数値を確認した上で利用してください。 また、私自身は 21.4 環境での動作確認しか行っていません。

elisp ファイルの読み込み

Emacs 用フロントエンドの elisp ファイルは:

Windows バイナリ版:
インストール先の "Contrib" 配下
Linux 系バイナリ版:
"/usr/share/doc/mercurial-版数/contrib" 配下
Cygwin の setup.exe 経由での導入:
elisp ファイルは含まれていませんので、別途入手が必要です。
ソース版:
ソースツリーの "contrib" 配下

に格納されていますので、 Emacs 起動時にこれを読み込む設定を行います。

elisp ファイルの格納場所を LOCATION と表記した場合の読み込み設定は、 以下のようになります。

(push "LOCATION" load-path)
(load-library "mercurial")
(load-library "mq") ;; MQ(Mercurial Queue) で patch 管理をする場合
フロントエンド elisp ファイルの読み込み

なお、 ログメッセージやファイル名に日本語を使用する場合には 「文字コード」、 特に「Emacs の hg モード利用における留意点」 を参照してください。

hg モード

"hg-help-overview" ("C-c h h") で表示されるキーマップ一覧には、 未実装機能や列挙されていない機能があります。

0.9.5 版に同梱される mercurial.el で利用可能な機能を以下にまとめました。

hg コマンド 対象 キー lisp 関数 C-u 指定
add ファイル C-c h a hg-add ファイル
cat ファイル C-x v ~ hg-version-other-window リビジョン
commit リポジトリ C-c h c hg-commit-start ---
ファイル C-x v n
diff リポジトリ C-c h = hg-diff-repo ファイル、リビジョン(-r)
ファイル C-x v = hg-diff
incoming リポジトリ C-c h , hg-incoming 対象リポジトリ
log リポジトリ C-c h l hg-log-repo ファイル、 対象範囲(-r)、 上限(-l)
ファイル C-x v l hg-log
outgoing リポジトリ C-c h . hg-outgoing 対象リポジトリ
pull リポジトリ C-c h < hg-pull 対象リポジトリ
push リポジトリ C-c h > hg-push 対象リポジトリ
revert ファイル C-x v u hg-revert-buffer ----
status リポジトリ C-c h s hg-status ファイル

「C-u 指定」欄に記述されているのは、 Emacs での当該機能実行のキー入力に先立って C-u を入力した場合に、 指定可能となる追加パラメータです。

キーバインドは、 リポジトリを対象とする機能が "C-c h"("h" は "hg" 由来) で始まり、 ファイルを対象とする機能が VC モードと同様に "C-x v" で始まるのが基本です。 但し、「ファイルの構成管理への追加」に関しては、 ユーザの感覚としてはファイルを対象とした操作ですが、 "C-c h" で始まるキー入力となります。

他リポジトリ連携

他リポジトリからの取り込み(hg-pull) は入力リダイレクト("<")、 他リポジトリへの反映(hg-push) は出力リダイレクト(">") に由来するキーバインドになっています。

また、 取り込み内容の事前確認(hg-incoming) は "<" キーの Shift 非押下であるカンマ(",")、 反映内容の事前確認(hg-outgoing) は ">" キーの Shift 非押下であるピリオド(".") に対応したキーバインドになっています。。

これらの関係を理解しておけば、 キーバインドを思い出すきっかけになるでしょう。

commit

コミットログ入力画面では、 以下の機能が使用可能です。

機能 キー lisp 関数
コミットの実行 C-c C-c hg-commit-finish
コミットの中断 C-c C-k hg-commit-kill
リポジトリ全体の変更内容表示 C-x v = hg-diff-repo

コミットログ入力画面には、 コミット対象と成り得るファイルが列挙されます。

列挙されたファイル名 ("M" や "A" といった状態マーク上では機能しないので注意) の上で SPACE や ENTER を押すことで、 コミット対象化の切り替えを行うことができます。 強調表示の有無が、コミット対象化の有無に相当します。

diff

"hg-diff-repo"("C-c h =") ないし "hg-diff"("C-x v =") による差分表示画面では、 ENTER 入力による該当差分箇所へのジャンプ ("diff-goto-source")に代表される diff モードの機能が使用可能です (diff モードのバージョンによっては "C-c C-c" にのみキーバインドされている場合があります)。

revert

elisp 上は "hg-forget" 機能が定義されていますが、 現在 "hg forget" は "hg revert" に統合されていますので、 Emacs 経由での使用においても "hg-revert" を使用してください。

mq モード

以下の Mercurial Queue(MQ) 連携が Emacs 経由で可能です。

hg コマンド キー lisp 関数 C-u 指定
qdiff C-c m = mq-diff git 互換
qnew C-c m i mq-new ----
qnext C-c m n mq-next ----
qpop C-c m , mq-pop パッチ名
qpop -a C-c m < mq-pop-all ----
qprev C-c m p mq-previous ----
qpush C-c m . mq-push パッチ名
qpush -a C-c m > mq-push-all ----
qrefresh C-c m r mq-refresh git 互換
qrefresh -m C-c m e mq-refresh-edit ----
qseries C-c m s mq-edit-series ----
mqrefresh -e C-c m o mq-signoff ----
qtop C-c m t mq-top ----

トラブルシューティング

Emacs 経由の Mercurial 連携において、 よくある問題とその解決のいくつかを列挙します。

モード行に "Hg:" が表示されない

Mercurial 管理下にあるファイルを開いた際、 モード行のモード表示部分には以下のような表示を見ることができます。

filename    (Fundamental  Hg:rev)
Mercurial 管理下ファイルのモード行

"filename" および "Fundamental" 部分は読み込んだファイルに応じて、 また "rev" 部分は作業領域の親チェンジセットに応じて変化しますが、 重要なのは "Hg:" 部分の表示の有無です。

Mercurial 管理下にあるファイルを開いた際に、 この "Hg:" が表示されない場合は、 以下のような問題が考えられます。

実は Mercurial 管理下に無い:

Emacs 経由以外の手段を使って、 当該ファイルが Mercurial で管理されているか否かを確認してください。

elisp ファイルが正しく読み込めていない:

"hg-mode" 関数の説明を表示させてみてください。 説明が表示されないようなら elisp ファイルの読み込みに失敗しています。

*Messages* バッファ等を参照して、 問題を解決してください。

hg コマンドの起動に失敗している:

次節「コマンド起動に失敗する」を参照してください。

hg コマンド起動に失敗する

Emacs が以下のようなメッセージを表示するのは、 hg コマンドの起動に失敗しているためです。

"Searching for program: no such file or directory, ...":

hg コマンドが見つからない場合です。

"hg-binary" 変数の値が期待する値になっているかを確認してください。 期待する値になっていないのは、 Emacs 起動後に Mercurial のインストール先を変更、 といったことが原因と思われます。

"Spawning child process: exec format error":

起動しようとしている hg コマンドが Python スクリプトであるため、 Windows 環境下において Emacs プロセスから hg コマンドが実行できない場合です。

スクリプト起動用補助プログラムのインストール」 を参照してください。

他リポジトリとの連携で応答がなくなる

ローカルリポジトリとの連携(e.g.: add/diff/log/commit 等)は正常に機能している一方で、 ssh 経由での他リポジトリとの連携(e.g.: push/pull 等)において応答が無くなる場合は、 以下のような原因が考えられます。

ホスト側公開鍵の受け入れでブロックされている:

当該ホストへの ssh 初回アクセス時には、 ホスト側公開鍵の受け入れ ("~/.ssh/known_hosts" ファイルへの追加) 是非の確認が必要です。

新たなホストに接続する場合は、 Emacs を経由しない ssh 利用で当該ホストにアクセスすることで、 ホスト側公開鍵の受け入れを済ませておく必要が有ります。

パスフレーズ入力でブロックされている:

ssh-agent 連携が機能していない (あるいは ssh-agent そのものを利用していない)場合、 ssh はパスフレーズが入力されるまで待ち続けます。

まずは Emacs を経由しない ssh 利用が、 パスフレーズ入力を要求しないことを確認してください。

それでも Emacs 経由での他リポジトリ連携が機能しない場合は、 ssh-agent により "SSH_AUTH_SOCK" 環境変数が設定される前に Emacs が起動されたために、 Emacs から fork された ssh が ssh-agent と連携できていないことが原因です。 適宜 Emacs を再起動してください。

パスワード認証でブロックされている:

当該ホストとの ssh 連携がパスワード認証で行われる場合、 ssh-agent は機能しません。

この場合、ssh によるリモートリポジトリとの連携を Emacs 経由で実施することはできません。

ちなみに、 tty 制御可否の関係上、 Emacs 上で稼動しているシェルからの ssh 利用も制限を受け (る可能性があり)ますので、 「Emacs を経由しない ssh 利用」においては、 Emacs の shell モードを使わないように注意してください。

SPACE/ENTER による機能起動が行われない

「コミットログ入力画面でファイルの選択ができない」、 「差分表示画面で該当行にジャンプできない」 といった問題がある場合、 以下のような原因が考えられます。

強調表示を行うことができない:

機能上は問題なくても、 フォントが不足(GUI 起動時)していたり 色設定等の問題(CUI 起動時)から、 強調表示ができないために、 一見するとファイルの選択ができないように見えることがあります。

この場合はフォント設定(場合によってはフォントのインストール) や色設定の見直しが必要です。

他の拡張機能との競合:

拡張機能の中には、 (Mercurial 連携に限らず) diff モード等と相性がよろしくないものがあります。

その場合は各自の「好み」に応じて、 拡張機能の取捨選択が必要になるでしょう。

日本語のログメッセージ・ファイル名が正しく扱えない

Emacs の hg モード利用における留意点」を参照してください。


次節「TortoiseHg からの利用」へ