彷徨えるフジワラ

年がら年中さまよってます

カスタムツールで TortoiseHg を機能拡張

このエントリはTortoiseHg Advent Calendar 2012の17日目です。既に日付が変わってしまっていますが、私が寝るまでが17日です。

後でやろうと思っていたら既にやられていた。何を言っているかわからねーと思うが(略)

全ての始まりは、以下のツイートを目にしたことでした。

それって、良くある『プログラムラウンチャ』の TortoiseHg 版みたいなのがあれば解決するよなぁ、と思って:

などと返信してみたものの、そんな機能は無いだろうから、新規作成かぁ、流石に TortoiseHg のパッチ作成とかに手を出す余裕は無いよなぁ、とりあえず時間ができたらソースでも見ておくか、という流れでマイ TODO リスト入りして放置状態になること暫し。

10月頃に、ウェブ上で『カスタムツールバー』とか言う単語を目にして、何気無しに情報を辿ってみると……あれ? TortoiseHg 2.4 版で、既に『カスタムツール』(custom tool)とか言う機能が利用可能になってるの!?

後になって見返してみたら、mercurial-ja での西原さんの2.4 のリリースアナウンスで:

amend 対応とカスタムツールバー(alias の GUI 版みたいなもの)以外は、不具合修正と細かな改善になります。

って書いてある……orz

そーかー、このリリースアナウンスを見た記憶とか、TortoiseHg のツールバーの右クリックで表示されるチェックメニューとかが、潜在意識に残ってたんだろうなぁ。

ということで、僕自身の個人的な感覚では、棚ボタ式に手に入った機能なので、折角だから使い倒してやれ!というのが、このエントリの趣旨です。

っていうか、既にある機能を、さもまだ実装されて無いかのように語ってしまって御免なさい > @toruuetani 氏

カスタムツールの作成

『ファイル』メニューから『設定』を選択して、『設定』ダイアログを表示させてください。『設定』ダイアログの『Tools』分類が、カスタムツール設定の起点になります。

まずは、『New Tool』を押し、表示される『Configure Custom Tool』ダイアログで、カスタムツールを定義します。

ここでは、以下の設定を行うことで、『選択したリビジョンの親リビジョンを表示』するカスタムツールを定義します。


  • Tool name ⇒ showparents
  • Command ⇒ hg --repository "{ROOT}" parents --rev "{REVID}"
  • Tool label ⇒ show parent revisions
  • Tooltip ⇒ show parent revisions
  • Icon ⇒ 無指定
  • On repowidget, show for ⇒ All revisions
  • Show Output Log ⇒ True

『OK』を押して、カスタムツールの定義は完了です。

カスタムツールの有効化

カスタムツールは定義しただけでは使えません。

『custom-toolbar』が選択されているのを確認した上で、『showparents』を選択し、『Add to list』を押します。

カスタムツール『showparents』が左側に表示されたなら、カスタムツールの有効化は完了です。

『OK』を押して『設定ダイアログ』を終了すると、『設定反映のためには再起動が必要』な旨が表示されるので、言われた通りに TortoiseHg を再起動してください。

再起動して、任意のリポジトリを開くと、ツールチップとして『show parent revisions』を表示する新しいボタンが、ツールバー領域に表示されている筈です。


カスタムツールの実行

それでは早速カスタムツールを実行してみましょう。

適当なリビジョンを選択した上で、ツールバーの『show parent revisions』ボタンを押してみましょう。

指定リビジョンに対する "hg parents" の実行結果が表示されたでしょうか?

ちなみに、調子に乗って作業領域を選択した状態から実行すると、コマンド実行でエラーが発生します……orz

カスタムツールをツールバーに表示した場合、リビジョン選択時しか使えない設定のカスタムツールのボタンが、作業領域選択時も無効化されない、という TortoiseHg のバグ(?)が原因です。

TortoiseHg コミッタの西原さんに報告済みなので、次の版で直っていることを期待しましょう(笑)。

カスタムツールの詳細

カスタムツールの詳細を理解するには、カスタムツールの設定を保存した後に、保存先の設定ファイルを覗いてみるのが一番です。

[tortoisehg]
workbench.custom-toolbar = showparents

上記の設定は、カスタムツールバーに "showparents" で定義したカスタムツールを表示せよ、という設定です。

複数のカスタムツールや、カスタムツールの間に区切り線を表示する場合は、カスタムツール名または "|" を、空白区切りで並べます。

[tortoisehg]
workbench.custom-toolbar = showparents | showheads | showbranches

なお、"workbench.revdetails.custom-menu" に対してカスタムツール並びを指定した場合は、リビジョン選択時の右クリックで表示されるコンテキストメニューの『カスタムツール』経由で、列挙したカスタムツールを選択することができます。

個々のカスタムツールは、以下のように定義されます。

[tortoisehg-tools]
showparents.command = hg --repository "{ROOT}" parents --rev "{REV}"
showparents.enable = isrev
showparents.showoutput = True
showparents.label = show parent revisions
showparents.tooltip = show parent revisions

カスタムコマンド実行時には、'command' 設定値に対して、以下の文字列置換が実施されます。

  • {ROOT}: 実行対象リポジトリのフルパス
  • {REV}: 選択対象リビジョンのリビジョン番号
  • {REVID}: 選択対象リビジョンのハッシュ値

但し、{REV} の値は選択対象によって以下のように変化します。

  • 既存リビジョンの場合は、リビジョン番号
  • 作業領域の場合は "None"
  • 未適用パッチの場合は、パッチ名

その一方で、{REVID} の値は:

  • 既存リビジョンの場合は、12桁ハッシュ値
  • 作業領域の場合は、親リビジョンの12桁ハッシュ値 + "+" 文字(例: "35800e03d26d+")
  • 未適用パッチの場合は、パッチに記録されたハッシュ値(無い場合は12桁の0)

という感じになります。作業領域選択時の値は、どちらにしても、外部コマンドの起動には使えなさそうな値ですね。

なお、(1) "hg" コマンドを実行していて、かつ (2) --repository によるリポジトリ指定がない場合、"--repository {ROOT}" 相当の引数が、末尾に勝手に追加されます。

また、指定したコマンド実行文字列は、内部での引数分解処理のために、バックスラッシュによるエスケープ処理が実施されます。

その副作用として、Windows のパス区切り文字もエスケープ文字とみなされてしまうため、引数指定の際には注意してください。

"{ROOT}" の置換はエスケープ処理の前に実施されるので、Windows 環境上で "{ROOT}" を併用する場合は、これもエスケープ処理の対象になってしまいます。かならずシングルクォートかダブルクォートで囲むようにしてください。

'enable' 設定は、設定画面での 'On repowidget, show for' に相当し、『カスタムツールを有効にすべき選択対象』を指定します。指定可能な選択肢は以下の通りです。

  • istrue (=All items): 常時
  • iswd (=Working Directory): 作業領域選択時
  • isrev (=All revisions): リビジョン選択時
  • isctx (=All contexts): 作業領域かリビジョン選択時のみ
  • fixed (=Fixed revisions): MQパッチ由来以外のリビジョン選択時
  • applied (=Applied patches): 適用済みパッチ選択時
  • qgoto (=qgoto): 作業領域か適用済みパッチ選択時

なお、コンテキストメニュー経由でカスタムツールを実行する場合には、作業領域を選択した際に、isrev (=All revisions) が指定されたカスタムツールのメニュー項目は、期待通りに非活性化されるため、先述した『想定外の対象(= 作業領域)に対してカスタムコマンドが実行できてしまう』問題は発生しません。

'showoutput' 設定は、設定画面での 'Show Output Log' に相当します。

この値が True の場合、カスタムコマンド実行時には、コマンドログが強制表示されます。

コマンド出力の参照を前提とするようなカスタムツールでは True を設定しましょう。

'label' や 'tooltip' 設定に関しては、説明の必要はないでしょう。

ちなみに、GUI 経由でカスタムツールの有効化設定をすると、設定終了後に『再起動しろや、ゴラァ!』(意訳)と言ってきますが、リポジトリ毎設定でカスタムツールを有効化した場合は、TortoiseHg 自体を再起動しなくても、一旦リポジトリを閉じてから、再度開くことで、カスタムツールが使用できるようになります。

但し、リポジトリ毎設定でカスタムツールの有効化を行うと、ユーザ毎設定での有効化は無視(= リポジトリ毎設定で上書き)されてしまうので、注意してください。

カスタムツールへの期待

現状のカスタムツールは、リビジョンの複数選択に対応していないため、ある程度以上に高度な作業を行う際には、まだ適用が難しいケースもあることでしょう。

しかし、特別なプログラミングなどをしなくても、複数処理の一括実行とか、特別なオプション/パラメータ指定でのコマンド実行などを、容易に TortoiseHg GUI 経由で実行できる、という拡張性には、非常に期待させるものを感じます。

皆さんも、カスタムツールをバリバリ使って、バグや機能拡張要望をジャンジャン報告しましょう!