git-grepでPerlの正規表現が使える…ぞ?

git-grep -P

Git 1.7.6から、git-grep -P でPCRE(Perl Compatible Regular Expressions)を使えるようになったらしい!PCREはPOSIX正規表現よりずっと表現力があって使いやすいし、なにより私は正規表現Perlで覚えたクチなので、扱い慣れた記法を使えるのは嬉しい。

$ git grep -P 'regex'
fatal: cannot use Perl-compatible regexes when not compiled with USE_LIBPCRE

あるえぇー?

Macports

GitはMacportsで入れているのだが、普通にインストールしただけだと有効にならない。*1エラーメッセージにある通り、現時点ではデフォルトでUSE_LIBPCREになっていないためである。

じゃあconfigureなりmakeなりに、-DUSE_LIBPCREとか食わせればいいんだろう?ということでport installするときに引数で渡せないかと調べたが、方法が見つからない。どうやらPortfileをいじってvariantを自力で追加するしかないようだ。

$ sudo port edit git-core

これでgit-coreのPortfileがエディタで上がってくる*2ので、これのおおむね下の方に下記の行を書き加える。*3 *4

variant pcre description {Use PCRE} {
  build.args-append       USE_LIBPCRE="YesPlease"
  destroot.args-append    USE_LIBPCRE="YesPlease"
  test.args-append        USE_LIBPCRE="YesPlease"
  depends_lib-append      port:pcre
}
default_variants +pcre

最後の一行はお好みで。default_variantsに定義しておくと、デフォルトで+pcreが適用されるようになる。

variantsを見ると、追加したpcreが追加されている。

$ port variants git-core
git-core has the variants:
   bash_completion: Completion support for bash
[+]doc: Install HTML and plaintext documentation
   gitweb: Install gitweb.cgi
[+]pcre: Use PCRE
   python26: Use Python 2.6
     * conflicts with python27
[+]python27: Use Python 2.7
     * conflicts with python26
   svn: Bi-directional subversion repository support
   universal: Build for multiple architectures

再インストール

git-coreをインストールし直す。variantはお好みで。

$ sudo port install git-core

pcreをdefault_variantsにしなかった人は、こんな感じ。

$ sudo port install git-core +pcre

これでOK。

$ git grep -n -P '\d(\.\d)+'
COPYING:4: v2.2 or v3.x or whatever), unless explicitly otherwise stated.
Documentation/CodingGuidelines:63:   just fine (e.g. dash older than 0.5.4).
Documentation/Makefile:66:#     -7.1.2, set ASCIIDOC7
Documentation/Makefile:67:#     8.0-,   no extra settings are needed
Documentation/Makefile:72:#     -1.68.1,        no extra settings are needed?
...

なにこれ便利!

git-grep

ところで、そもそもgit-grepなんて知らないよ、grep -Rとかrakとか使ってるし、という人も結構いるんじゃないかと思う*5

しかし、git-grepgrepと同じ操作感でGit特有の便利機能も持っている、思いの外使い勝手の良いコマンドである。例えば、 特定の文字列を含むファイルを大文字小文字の違いを気にせず検索するには、次のようにするだけでいい。

$ git grep -i 'pattern'

これだけで作業コピー内のファイルを勝手に検索してくれる(検索対象のファイルを指定しなくていいし、もちろん指定してもいい)し、この際 .git/ や無視ファイルをデフォルトで検索対象から除外してくれる点もまた便利である。

むろんGitユーザであると同時に敬虔なるVimmerでありESCを狂おしく連打する日常を送っておられるはずの諸兄にあっては、当然偉大なるvim-fugitiveを使っておられるであろうから、 :Ggrep だけで実行できてお手軽である。あまつさえ直後に :copen してしまった日には…!

あと、次のようにしておくと、毎回行番号を見るために -n を付けなくて良くなるので、また少し便利になる。

$ git config --global --add grep.lineNumber true

*1:Homebrewでもそのままだと使えないっぽい。

*2:$EDITOR環境変数を設定しておくこと。

*3:他の定義を見よう見まねで書いているので、無駄があるかも。

*4:"YesPlease"はGitのソースコードから拾ってきた値で、実際はなんでもいいはず。

*5:つい先日まで私もそうでした!