1. ホーム
  2. git

[解決済み] Gitの履歴からコミットしたコードをgrep(検索)する方法

2022-03-20 23:23:46

質問

過去にファイルやファイル内のコードを削除したことがあります。コミットメッセージではなく、その内容をgrepすることは可能でしょうか?

非常に悪い解決策は、ログを grep することです。

git log -p | grep <pattern>

しかし、これではコミットハッシュがすぐに返ってきません。そこで git grep を実行しても無駄です。

解決方法は?

コミットを検索するには コンテンツ (つまり、コミットメッセージなどとは対照的な、ソースの実際の行) を実行する必要があります。

git grep <regexp> $(git rev-list --all)

git rev-list --all | xargs git grep <expression> は、"Argument list too long"エラーに遭遇した場合、動作します。

検索対象をサブツリー (たとえば "lib/util") に限定したい場合は、そのサブツリーを rev-list サブコマンドと grep にも対応しています。

git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util

これは、すべてのコミットテキストを grep して regexp .

両方のコマンドでパスを渡す理由は、以下の通りです。 rev-list に対するすべての変更が含まれるリビジョンリストを返します。 lib/util に渡す必要があります。 grep のみを検索するようにします。 lib/util .

ただ、次のようなシナリオを想像してみてください。 grep は、同じ <regexp> が返す同じリビジョンに含まれる他のファイル上で rev-list (たとえそのリビジョンでそのファイルに変更がなかったとしても)。

その他、ソースを検索するのに便利な方法を紹介します。

正規表現regexpにマッチするテキストを作業ツリーで検索します。

git grep <regexp>

正規表現 regexp1 または regexp2 にマッチするテキスト行を作業ツリーに検索します。

git grep -e <regexp1> [--or] -e <regexp2>

正規表現 regexp1 と regexp2 に一致するテキスト行を作業ツリーに検索し、ファイルパスのみを報告する。

git grep -l -e <regexp1> --and -e <regexp2>

正規表現regexp1にマッチするテキスト行と正規表現regexp2にマッチするテキスト行を持つファイルを作業ツリーから検索します。

git grep -l --all-match -e <regexp1> -e <regexp2>

作業木を検索して、パターンに一致する変更されたテキスト行を探す。

git diff --unified=0 | grep <pattern>

正規表現 regexp に一致するテキストをすべてのリビジョンで検索します。

git grep <regexp> $(git rev-list --all)

正規表現 regexp に一致するテキストについて、rev1 と rev2 の間のすべてのリビジョンを検索します。

git grep <regexp> $(git rev-list <rev1>..<rev2>)