ブランチに文字列を導入したGitコミットを見つける方法は?


396

ブランチのコミットで導入された特定の文字列を見つけられるようにしたいのですが、どうすればよいですか?(Win32用に変更した)何かを見つけましたがgit whatchanged、別のブランチを調べているようには見えません(py3kチャンクは無視してください。これはmsys / winの改行修正です)

git whatchanged -- <file> | \
grep "^commit " | \
python -c "exec(\"import sys,msvcrt,os\nmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\nfor l in sys.stdin: print(l.split()[1])\")" | \
xargs -i% git show origin % -- <file>

ソリューションが遅いかどうかは問題ではありません。


回答:


685

できるよ:

git log -S <whatever> --source --all

固定文字列 を追加または削除したすべてのコミットを検索するwhatever--allパラメータ手段は、すべての枝から開始して--sourceコミットの発見につながったものを枝のどの示すために、手段。多くの場合-p、これらのコミットのそれぞれが導入するパッチを表示するために追加すると便利です。

1.7.4以降のバージョンのgitにも同様の-Gオプションがあり、正規表現を使用します。これは実際には異なる(そしてより明白な)セマンティクスを持っています。これは浜野純雄のこのブログ投稿で説明されています。

以下のようthameeraコメントにポイントアウト、あなたはそれがスペースやその他の特殊文字が含まれている場合、たとえば、検索語の前後に引用符を配置する必要があります。

git log -S 'hello world' --source --all
git log -S "dude, where's my car?" --source --all

以下は、の-G出現を検索するために使用する例ですfunction foo() {

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all

19
卓越性のための+1。-Sを指すことは1つのことです。また、私は--decorateを使用して、どのブランチからのものかを確認します
sehe

7
@sehe:素敵なコメントをありがとう。--decorate各ブランチの先端にあるコミットにブランチ名を追加するだけであることに注意する価値があると思います。実際に私は本当に使用していない--source--decorate、代わりに使用しgit branch -a --contains <commit-hash>、私が興味を持っていますコミット含んでいる枝を見つけるために。
マークLongairを

3
-pを追加すると、インライン差分、FWIW
rogerdpack、

1
@MarkLongairでは、マージで加えられた変更は表示されません。それらも表示するための提案はありますか?
Pahlevi Fikri Auliya

2
私にとって、これは-Sと検索語の間のスペース削除した場合にのみ機能しgit log -S"dude, where's my car?" --source --allます。@ribamarも以下の回答でそれを書きましたが、このトップ回答の横に見落とされがちです。
バグ313


20

マーク・ロングエアの答えはすばらしいですが、私はこの単純なバージョンがうまくいくと感じました。

git log -S whatever

24
明確にするために、探しているコミットがにある場合は問題なく動作しますHEADが、この特定の質問では、リポジトリ内のすべてのブランチを調べることについて具体的に質問しました。
Mark Longair 2013

18

同じ答えでいじくります:

$ git config --global alias.find '!git log --color -p -S '
  • 他の方法では、gitが-Sに引数を正しく渡さないため、これが必要です。この応答を見る
  • --colorおよび-pは、正確に「何が変更されたか」を示すのに役立ちます

今できる

$ git find <whatever>

または

$ git find <whatever> --all
$ git find <whatever> master develop

6
git log -S"string_to_search" # options like --source --reverse --all etc

Sと "string_to_search"の間にスペースを使用しないように注意してください。一部のセットアップ(git 1.7.1)では、次のようなエラーが表示されます。

fatal: ambiguous argument 'string_to_search': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

2

これは直接あなたの質問に答えるものではありませんが、将来的にはあなたにとって良い解決策になると思います。私は自分のコードの一部を見ましたが、それは悪かったです。誰がいつ書いたかわかりませんでした。ファイルからのすべての変更を確認できましたが、コードが他のファイルからこのファイルに移動されたことは明らかでした。そもそも実際に誰が追加したのかを知りたかった。

これを行うには、Git bisectを使用しました。これにより、罪人をすぐに見つけることができました。

私が走ったgit bisect start当時とgit bisect badリビジョンは問題があったチェックアウトしたので、。問題がいつ発生したのかわからなかったので、「良い」最初のコミットを対象にしましたgit bisect good <initial sha>

それから私はちょうど悪いコードのためにリポジトリを検索し続けました。それを見つけたとき、私は走りましたgit bisect bad、そして、それがそこになかったとき:git bisect good

〜11ステップで、私は〜1000コミットをカバーし、問題が導入された正確なコミットを見つけました。かなり素晴らしい。


2

受け入れられた回答が私の環境で機能しない理由がわからない、最後に以下のコマンドを実行して必要なものを取得します

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.