彷徨えるフジワラ

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

TortoiseHg の独自機能 〜 サブリポジトリのファイル検索

このエントリは、Mercurial Advent Calendar 2013 の15日目です。

このエントリでは、前回の「TortoiseHg の独自機能 〜 サブリポジトリの状態表示」に引き続き、TortoiseHg が独自に提供している機能として、「サブリポジトリのファイル検索」について説明しようと思います。

ファイル内容の検索

Mercurial の基本機能の範囲では、コマンドラインにおいて「指定パターンと合致する行を持つファイルを検索し、合致行の内容を表示」する機能は提供されていません。このことは、拙著「入門 TortoiseHg + Mercurial」の「12.3.1 特定文字列が含まれるファイルの検索」でも説明しました。

入門TortoiseHg+Mercurial

入門TortoiseHg+Mercurial

かろうじて、filesets 記述を使って「指定パターンと合致する行を持つファイルを検索」することができるだけです。

$ hg locate "set: grep('内容に対するパターン指定')"

一方 TortoiseHg は、ツールバーの「検索」(又は「表示」メニュー⇒「検索」)で表示される検索ペインにおいて、「作業領域」を選択した上で、パターン入力 ⇒ 「検索」押下により、パターンに合致する行を列挙することができます。

コマンドラインで同等の機能を得るには、古典的な xargsgrep との組み合わせ(あるいはそれに類するコマンド)を使用するか:

$ hg locate | xargs grep -n "内容に関するパターン指定"

id:troter さんの手による grepfile エクステンションを使用する必要があります。

$ hg grepfile -n "内容に関するパターン指定"

サブリポジトリも含めたファイル内容の検索

さて、それではサブリポジトリ中のファイルも検索対象に含めたい場合はどうでしょう?

コマンドラインからの検索実行で、サブリポジトリ中のファイルも検索対象に含めようとするなら:

$ hg status -acm -n -S | xargs grep -n "内容に関するパターン指定"

上記のような方法で頑張る必要があります。

hg locatehg manifest は、サブリポジトリ中のファイルの列挙ができないので、-S--subrepos) オプションを持つ hg status で代替しています。-acm オプションは「追加」「変更なし」「変更あり」のファイルの列挙を、-n オプションは xargs 向けに状態マークの出力を抑止するためのものです。

また、grepfile エクステンションに関しては、現時点ではサブリポジトリに対する検索をサポートしていません。

一方 TortoiseHg は、検索ペインにおいて、「サブリポジトリを含む」にチェックを入れることで、サブリポジトリ中の作業領域に対しても、「指定パターンと合致する行を持つファイルを検索し、合致行の内容を表示」することが簡単にできます。

以前のエントリの件もありますから、普段コマンドラインから Mercurial を使用している人も、サブリポジトリを使用する場合は TortoiseHg 経由での作業を検討してみる価値はあると思います。

なお、上記検索ペインにおいて、検索対象として「作業領域」が選択されていても、「サブリポジトリを含む」がチェックできない場合があります(バグ修正済みなので、2.11 版からは改善される予定)。

そのような場合は、検索対象を一旦「全履歴」あるいは「リビジョン」に変更してから、再度「作業領域」を選択すれば、「サブリポジトリを含む」がチェックできるようになります。

履歴検索における性能劣化要因

ファイル内容の検索とは関係ありませんが、grepfile エクステンション繋がりで、実装周りの問題の話を、もう一点、

折角なので、grepfile エクステンションにサブリポジトリ対応の修正を加えて、pull request しようかと思い、grepfile 自身のコードや、コード片の引用元と思われる hg grep コマンドのコードを調べていたら、同一のファイル内容に対して、以下のような二重の読み込みを行うという、非効率な実装を発見してしまいました。

  • ファイル内容に対する検索のための読み込み
  • ファイルがバイナリファイルか否かを判定するための読み込み

160リビジョン程度の履歴を持つ、30Kバイト(1K行)程度のファイルに対して、hg grep --all した場合、大体 8% 〜 10% 程度の性能劣化でした。

対象ファイルサイズが大きいほど、処理時間の大半を占める検索処理も重くなるため、多重読み込みによるコスト増加の影響は、相対的に低減する可能性があります。小さいファイルが大量にあるようなケースの方が、多重読み出しによるオーバヘッドの影響が出やすいかもしれませんね。

現在、修正パッチを鋭意作成中です。