2013-08-21 9 views
16

タイトルには、diffに特定の文字列が含まれているすべてのコミットがあります。現時点で diffに特定の文字列が含まれているすべてのコミットを表示します。

は、私は文字列を検索すべての差分、のインターフェースなどの少ない示し

git log -p 'filename' 

を使用しています。 次に、実際のコミットメッセージを見つけるためにバックトレースを行います。

単純な代替方法は、grepにgit log -pをパイプすることですが、コミットIDやメッセージを見つけられません。

+0

あなたは答え?私は他の答えがスクリプトよりも良いと信じています(実際には1行になります)。もう1つはより詳細な説明を提供します。 –

答えて

13

ここでワンライナーのシェルスクリプトです(フォーマット目的のために複数の行に分割されています)、現在のブランチ到達可能コミットのrev番号を抽出します。 g pathgit show -pは、与えられたpatternを含む。それは完全ではありません(コミットメッセージとdiffファイルは一致します)が、ここから好きなだけ微調整するのは簡単です。

git rev-list HEAD -- path | 
while read rev; do 
    if git show -p $rev | grep pattern >/dev/null; then 
     echo $rev 
    fi 
done 

あなたとgit showを置き換えることができます、例えば、git diff $rev^ $rev(それはマージだ場合、これが唯一の最初の親に対して比較していることに注意してください)、またはgit whatchanged $rev、またはものは何でも好きです。主なテクニックはgit rev-listで始まり、すべての候補を抽出します(指定されたパスに影響を与えるコミット、から開始するすべてのコミットを取得するには部分を省略します)。 git rev-listでできることの多くは、git-rev-list(1)を参照してください。

+0

1本のライナーに対してはあまりにも冗長すぎません(通常のシナリオでこれを使用する必要があります)。しかし、それはクリーンなソリューションであり、動作します。私は質問を次の24時間開いたままにしておき、よりよい解決策がない限り、あなたのことを受け入れます。助けてくれてありがとうございます – bbaja42

1

あなたは、Linuxを使っているのであれば、パイプそれegrepを通って、

git log -p 'filename' | egrep '(yourstring|commit-message)' 
+0

ええ、いいのですが、私は文脈を見ません。とにかくThnx。 – bbaja42

+0

@ bbaja42についてはどうですか? git log -p 'ファイル名' | egrep '(yourstring | commit-message)'を実行します。こうすれば、出力はコミットメッセージに続いて行が変更されたものになります。マッチの前後でより多くのコンテキストを取得するには、-Cフラグをegrepに渡すことができます。 – user1333371

+0

git log -p 'filename' egrep '(yourstring |コミットメッセージ)' | grep -B 1 yourstring。これは、コミットメッセージと一致する 'theString'のみを表示します。 – bbaja42

0

あなたはパイプとgrepコマンドを使用して考えがあります正規表現で検索しますか?

例:

git log -p | grep 'filename' 
+0

悪い考えではありませんが、実際にコミットメッセージが必要なので、そのコミットのコンテキストを取得できます。コミットがかなり大きいので、grepの-Cオプションを使用することはできません – bbaja42

0

次の例のように、このためにgitを使用することができます。

git log --grep="filename" 

または特定のファイルのを:

git log --grep="filename" README 
+0

--grepは実際のdiffではなく、コミットメッセージのみを検索します。 gitのヘルプログに基づいて – bbaja42

+0

Okを試してみてください git grep 'filename' $(git rev-list --all) –

20
git log -S'string' 

文字列を追加または削除するコミットを検索するために使用できます。これはパターンのインスタンスを実際に追加または削除するコミットにのみ一致し、diffコンテキストで発生する場所はコミットしないなど、まったく同じように動作しません。しかし、それはあなたのために十分です。

+0

ええ、私は試しましたが、あなたが言及したように、私の場合、必要なものすべてが表示されません。とにかくThnx、良い試み。 – bbaja42

+0

'git log -p -S'string'' – nroose

7

私はこの質問がしばらく答えられていることを知っていますが、私もこれを見つけて、別の解決策を見つけました。 Git-log-Gスイッチは、一致した文字列の出現数が変更された場合にのみ、-Sスイッチがコミットを出力することになります。

git-logのmanページから:パッチテキストが一致し追加/削除された行が含まれているの違いを

-G ルック。

は、同じファイルに次の差分をコミット考える-S --pickaxe-正規表現と-Gとの違いを説明するために:

+ return !regexec(regexp, two->ptr, 1, &regmatch, 0); 
... 
- hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0); 

gitのログ-G「regexecは(正規表現」だろうがこのコミットを表示するには、git log -S "regexec(regexp" --pickaxe-regexはその文字列の出現数が変更されなかったため)。

+0

Hooray!ありがとう!これは私にとって完璧に機能します。 –

+0

ところで、この組み込みの '-G'(grep for change)と私の長い" one-liner "の答えの違いは、この特定の' regexec'オカレンスを見つけることですが、* not * oneこれはちょうど 'git log -p'の出力で示された文脈の中にあります。たとえば、変更された行が 'regexec'呼び出しの直前の行であった場合、' git log -G'はその変更を検出しませんが、 'git show -p'コマンドの出力を検索すると、その変更は見つかりません。 (したがって、どのコマンドを試してみるかは、見つけたいものに依存します)。 – torek

関連する問題