リポジトリ内のすべてのGitおよびMercurialコミットで特定の文字列を検索する方法は?


287

いくつかのブランチとぶら下がっているコミットのGitリポジトリがあります。特定の文字列のリポジトリ内のすべてのそのようなコミットを検索したいと思います。

私は履歴内のすべてのコミットのログを取得する方法を知っていますが、これらにはブランチやぶら下がっているブロブは含まれず、HEADの履歴のみが含まれます。私はそれらをすべて取得し、見当違いの特定のコミットを見つけたいと思っています。

また、切り替えを検討しているので、Mercurialでこれを行う方法も知りたいです。


回答:


331

でダングリングコミットを確認できますgit log -g

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones. 

したがって、これを実行して、ぶら下がっているコミットメッセージ内の特定の文字列を見つけることができます。

git log -g --grep=search_for_this

あるいは、特定の文字列の変更を検索する場合は、ツルハシ検索オプション「-S」を使用できます。

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Git 1.7.4 では-Gオプション追加され、-G <regexp>を渡して<regexp>を含む行がいつ移動されたかを見つけることができますが、-Sではできません。-Sは、文字列を含む行の総数が変更されたときにのみ通知します(つまり、文字列の追加/削除)。

最後に、gitkを使用して、ダングリングコミットを視覚化できます。

gitk --all $(git log -g --pretty=format:%h)

そして、その検索機能を使用して、誤って配置されたファイルを探します。欠落しているコミットが「期限切れ」でなくガベージコレクションされていないことを前提としたこれらすべての作業は、30日間ぶら下がっていて、reflogを期限切れにするか、期限切れにするコマンドを実行した場合に発生する可能性があります。


4
おそらく、プロジェクト内のどこかに「search_for_this」を含むすべてのコミットを見つける(おそらく大量の)コミットで「git grep」を実行する代わりに、いわゆる「pickaxe」検索、つまりgit logに「-S」オプションを使用します。は、指定された文字列を導入または削除したコミット、または指定された文字列の出現回数が変更された場合により正確に検出されます。
JakubNarębski、2009

5
複数のブランチを指定するか、「
all

これにより、2日間分の作業で失われたコミットを見つけることができました。お尻を完全に保存しました、ありがとう!
Mike Chamberlain

2
データベースにコミットがあり、reflogにはコミットされていない状況に遭遇しました。これがどれほど一般的かはわかりません。さまざまなhg / gitブリッジを試していました。スタッシュが落ちた場合にも発生する可能性があります。いずれにせよ、このエイリアスはそれらのケースをキャッチするためにうまく機能します:!git fsck --unreachable | sed -ne 's/^unreachable commit //p' | xargs git log --no-walk
dubiousjim

これには、メモオブジェクトの検索は含まれません。これはまだ実装されていません。git.661346.n2.nabble.com/...
アントニー・スタッブス

54

Mercurial hg log --keywordでは、コミットメッセージでキーワードhg log --userを検索し、特定のユーザーを検索するために使用します。hg help logログを制限する他の方法については、を参照してください。


36
Josipは、Mercurialへの切り替えを検討しており、それがどのように行われるかについても聞きたいと書いています。
マーティンガイスラー、2010

1
hg log -k検索は、チェンジセット内のユーザー名とファイル名もコミットします(commands.py:logで確認できます)。これは、hgで理解できない数少ないものの1つです。コミットメッセージとファイル名を検索するための個別のオプションが必要です。以下のように思えるhg log --template '{desc}\n'|grepの確実な方法です。
Geoffrey Zheng

@GeoffreyZheng:それを行う方法があります。「hg help revsets」、esp、desc()、user()、file()関数を参照してください。この動作のほとんどには、hgログスイッチもあります。私の経験では、通常-k / keyword()が検索に最も役立つ方法です。
Kevin Horn

実際にコミットされたファイルのコンテンツをどのように検索するのですか...差分?遅い検索になることは承知していますが、不足している関数名を深く検索したいと思います。
ジョナサン

ああここにあります:hg grep --all <term>
ジョナサン

24

or の使用に関するrichq回答に加えて、現在のgitメンテナーであるJunio C Hamanoによる以下のブログ投稿をご覧ください。git log -g --grep=<regexp>git grep -e <regexp> $(git log -g --pretty=format:%h)


概要

git grepgit log --grepはどちらも、指定されたパターンに一致する行を探すという点で、行指向です。

を使用してgit log --grep=<foo> --grep=<bar>(またはgit log --author=<foo> --grep=<bar>内部的に2に変換して--grep)、いずれかのパターン(暗黙的ORセマンティック)に一致するコミットを見つけることができます。

行指向であることのなので、便利セマンティックが使用することですgit log --all-match --grep=<foo> --grep=<bar>見つけるためにコミットことがあり、両方の最初の行マッチングをし、ライン二どこかにマッチします。

ではgit grep、あなたが複数のパターン(使用しなければならないすべて組み合わせることができ-e <regexp>て、フォームを)--or(デフォルト)、 、、--and と。grepの場合、ファイルにはそれぞれの選択肢と一致する行が必要です。--not()--all-match


こんにちはJakub、これらのブログ投稿からの引用/要約をここに統合しますか?現在、ヴィンテージのリンクのみの回答の1つに見えます。
Nathan Tuggy

11

rqの答えに基づいて、私はこの行が私が望むことをするのを見つけました:

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

次のように、コミットID、ファイル名を報告し、一致する行を表示します。

91ba969:testFile:this is a test

...これが標準のgit grepコマンドに含まれる良いオプションであることに誰もが同意しますか?


5

引数として参照を受け取るコマンドはすべて、次のように--allマニュアルページに記載されているオプションを受け入れgit rev-listます。

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

したがって、たとえば、ブランチやタグからgit log -Sstring --all言及さstringれ、アクセスできるすべてのコミットが表示されます(私は、ダングリングコミットに少なくともタグが付けられていると想定しています)。


3
これはのためのケースであるようには見えないgit grep--allとして使用する/変換されますように見えます--all-match。これは私にはバグのようです。Git1.7.2.3を使用しています($(git rev-list --all)works を使用)。
11

5

Mercurialを使用すると、

$ hg grep "search for this" [file...]

検索されるリビジョンの範囲を絞り込む他のオプションがあります。


1
私も旗が好きですhg grep --all
ジョナサン

2

gitについてはわかりませんが、Mercurialでは、hgログの出力をパイプしてsed / perl / whateverスクリプトに送り、探しているものを検索します。必要に応じて、テンプレートまたはスタイルを使用してhgログの出力をカスタマイズし、検索しやすくすることができます。

これには、リポジトリ内のすべての名前付きブランチが含まれます。Mercurialには、ぶら下がっているブロブのようなものはありません。


1
この回答が特定の問題にどのように関連しているかはわかりません。
jribeiro 2013

3
これは、Mercurialに対する質問への回答であり、元の質問は最後の段落で尋ねています。
カートSchelfthout 2013


1

まだ言及されていないソリューションを1つだけ追加するには、gitgのグラフィカル検索ボックスを使用するのが最も簡単なソリューションであると言わざるを得ません。最初の出現箇所が選択され、Ctrl-Gで次の出現箇所を見つけることができます。


1

文字列を見つける方がはるかに簡単だと思うgitの1つのコマンド:

git log --pretty=oneline --grep "string to search"

Git 2.0.4で動作します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.