Git リポジトリ内のコードを grep 検索する (git grep)

git grep とは

Git に組み込まれている git grep コマンドを使うと、Git リポジトリ内のコードを対象にした grep 検索を行うことができます。 Linux の grep コマンドを使うのと比べて、次のような利点があります。

  • OS に依存しない grep コマンドとして使用できる
  • .gitignore で指定されているファイルを無視して検索してくれる
  • ある時点のコードを対象に検索できる(コミットハッシュの指定)
  • ある文字列を含む関数を検索できる(-p オプション)

git grep の基本

カレントディレクトリ以下を検索する
$ git grep "検索文字列"

カレントディレクトリ以下のファイルを対象として git grep するには、上記のように単純に検索文字列を指定するだけで OK です。 もちろん、Git 管理されているディレクトリ以下で実行する必要があります。

検索対象のディレクトリやファイルを指定するには、次のように -- で区切ってからディレクトリ名やファイル名のパターンを指定します。

src ディレクトリ以下を検索する
$ git grep "検索文字列" -- src
src ディレクトリ以下の .py ファイルを検索する
$ git grep "検索文字列" -- "src/**.py"

ワイルドカードを指定してファイル名のパターンを指定するときは、"src/**.py" のようにダブルクォートで囲む必要があることに注意してください。 これは、git grep にパラメーターが渡される前にシェルがファイルグロブとして展開してしまうのを防ぐためです。

特定のディレクトリやファイルを検索対象外にしたいときは、:^ というプレフィックスを付けます。

.github ディレクトリや package.json を検索対象外にする
$ git grep react -- :^.github ":^package*.json"

拡張正規表現を使って検索したいときは、-E オプションを指定します。

正規表現を使って検索する
$ git grep -E "https?://"

特定のコミットハッシュやブランチ、タグのコードを検索対象としたいときは、検索文字列の後ろにコミットハッシュなどを指定します。

コミットハッシュを指定して検索する
$ git grep "検索文字列" ba17d26

複数の検索パターンを AND や OR で組み合わせたいときは、-e 検索文字列(または -E 拡張正規表現)というパターン指定を、--and--or で繋げて指定します。

AND 検索(game と book を両方含む行を検索)
$ git grep -e "game" --and -e "book"
OR 検索(game または book を含む行を検索)
$ git grep -e "game" --or -e "book"

git grep の応用的な使い方

git grep のその他のオプションは、git grep -h で確認することができます。 例えば、次のようなオプションが用意されています。

  • -i, --ignore-case … 大文字・小文字を区別しない
    • 例: git grep -i "github"
  • -n, --line-number … 行番号を表示する
    • 例: git grep -n "foobar"
  • -w, --word-regexp … 単語境界を考慮する
    • 例: git grep -w "Git"__ (Git にはヒットし、GitHub にはヒットしなくなります)
  • -p, --show-function … ヒットした行を含む関数の先頭行も表示する
    • 例: git grep -p "findUsers" -- "*.ts"findUsers を呼び出している関数を探すことができます)
  • -h … 各行の先頭にファイル名を表示しない
  • --recurse-submodules … サブモジュールのコードも含めて検索する

関数名を検索できる -p, --show-function オプションなどは面白いですね。