Gitブランチでファイルまたはディレクトリを検索するにはどうすればよいですか?


323

Gitで、複数のブランチにわたるパスでファイルまたはディレクトリを検索するにはどうすればよいですか?

ブランチに何か書いたことがありますが、どちらを書いたか覚えていません。今、私はそれを見つける必要があります。

明確化:私は自分のブランチの1つで作成したファイルを探しています。内容がわからないので、内容ではなくパスで検索したいのですが。


質問は不明です。このファイルは現在削除されているブランチにありましたか?ファイルは削除されましたか?
Abizern 2008

回答:


444

git log+ git branchあなたのためにそれを見つけます:

% git log --all -- somefile

commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <dustin@spy.net>
Date:   Tue Dec 16 14:16:22 2008 -0800

    added somefile


% git branch -a --contains 55d2069
  otherbranch

グロビングもサポートします:

% git log --all -- '**/my_file.png'

(少なくともBashシェルを使用している場合は)単一引用符が必要なため、シェルは(Unixと同様にfind)グロブパターンを展開するのではなく、変更せずにgitに渡します。


2
これは、正確なパスがわかっている場合に機能します。somefileたとえば、パス/ファイル名に対して正規表現検索が必要な場合は、ididakの回答を使用できます。
ShreevatsaR 2012

70
あまりにも、グロブサポートしていますgit log --all -- **/my_file.png
webmat

3
これを少し異なる問題に使用しました。特定のブランチにコミットしたすべての* .sqlファイルを見つけようとしました。だから私は使用しましたgit log --grep='branch' --author='me' -- *.sql。魅力のように働いた。gitバージョン1.7.11.1
thepriebe

1
gitkは、グロビングもサポートしていることに注意してください。それは@webmatの素晴らしい答えです!削除/作成された/ etcの場所を確認したい場合は、を使用できgit log --all --stat -- **/my_file.pngます。これにより、削除されたコミットからチェックアウトしているかどうかを推測する必要がなくなります。
eacousineau 2013年

1
@webmat:グロビングに関するあなたの情報を答えに自由に追加しました。言及してくれてありがとう!
sleske 2014

65

git ls-treeが役立つかもしれません。既存のすべてのブランチを検索するには:

for branch in `git for-each-ref --format="%(refname)" refs/heads`; do
  echo $branch :; git ls-tree -r --name-only $branch | grep '<foo>'
done

これの利点は、ファイル名を正規表現で検索できることです。


3
役立つと思われるコメント:(a)「-r」を「git ls-tree」に追加して、ファイルがサブディレクトリにある場合でもファイルが見つかるようにする必要があります。(b)最初の行のおそらくより良い代替案は、「git for-each ref」を使用することgit for-each-ref --format="%(refname)" refs/headsです。たとえば、「for branch in ; do」(c)「git ls-tree --name-only」は、出力をより整然とします。 (d)ダスティンのソリューションよりも優れている点、つまり、ファイル名を正確に知る必要がないという回答で指摘する価値があるかもしれません-パスの任意の部分に一致する正規表現で検索できます
Mark Longair

9
これをスクリプトにまとめたので、「gitfind.sh <regex>」を実行できます。要点はgist.github.com/62d981890eccb48a99dc
Handyman5

3
これはローカルブランチのみを検索することに注意してください。リモート追跡ブランチを検索するrefs/remotesには、の代わりにを使用しますrefs/heads。すべて(ローカルブランチ、リモートトラッキングブランチ、タグ)を検索するには、を使用しますrefs/
sleske 2013

19

ididakの応答はかなりクールで、Handyman5はそれを使用するスクリプトを提供し、私はそれをそのアプローチを使用するように制限された少しを発見しました。

時々出現/消失する可能性があるものを検索する必要がある場合があるので、すべてのコミットに対して検索しないのはなぜですか?その上、時には詳細な応答が必要なこともあれば、マッチをコミットするだけのこともあります。これらのオプションの2つのバージョンを次に示します。これらのスクリプトをパスに配置します。

git-find-file

for branch in $(git rev-list --all)
do
  if (git ls-tree -r --name-only $branch | grep --quiet "$1")
  then
     echo $branch
  fi
done

git-find-file-verbose

for branch in $(git rev-list --all)
do
  git ls-tree -r --name-only $branch | grep "$1" | sed 's/^/'$branch': /'
done

今できる

$ git find-file <regex>
sha1
sha2

$ git find-file-verbose <regex>
sha1: path/to/<regex>/searched
sha1: path/to/another/<regex>/in/same/sha
sha2: path/to/other/<regex>/in/other/sha

使用していることを参照してくださいgetoptのことなど、冗長となって、あなたが別の検索にすべてのコミット、レフリー、レフリー/ヘッドをそのスクリプトを変更することができます

$ git find-file <regex>
$ git find-file --verbose <regex>
$ git find-file --verbose --decorated --color <regex>

チェックアウトhttps://github.com/albfan/git-find-file可能な実装のために。


「git-find-file <regex>を実行できるようになりました」という意味ですか?うまくいきました、ありがとう!
Elijah Lynn

1
個人的には、$(git rev-list --all)の代わりに$(git branch | cut -c 3-)を使用する方がはるかに便利です。コミットの束を見つけることは気にしません。名前付きブランチを気にします。
カンパドレナリン

また、すべてのコミットのループが非常に遅かったため、$(git branch | cut -c 3-)を使用するようにスクリプトを変更しました。
i4h

このためのレポを作成する価値があるすべての大騒ぎを見てください。github.com/albfan/git-find-file。私はいくつかの問題を抱えています。もっと提案したり、PRを送ったりしてください。
albfan 2015年

1
パス上の@lumbricインストールスクリプトはそのまま使用できます。これはgit機能です
albfan 2016年

10

gitk --allコミットを使用して「タッチパス」と興味のあるパス名を検索できます。


3
述べたように、gitk --allを使用してから、View | 新しいビュー、すべてのブランチを有効にします。次に、最後から2番目のフィールドにファイル名(ワイルドカードを含む)の検索基準を設定します。最後に:OK。
MikeW 2016年

8

これをコピーして貼り付けて使用します git find-file SEARCHPATTERN

検索されたすべてのブランチを印刷する:

git config --global alias.find-file '!for branch in `git for-each-ref --format="%(refname)" refs/heads`; do echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; done; :'

結果のあるブランチのみを印刷します。

git config --global alias.find-file '!for branch in $(git for-each-ref --format="%(refname)" refs/heads); do if git ls-tree -r --name-only $branch | grep "$1" > /dev/null; then  echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; fi; done; :'

これらのコマンドは、いくつかの最小限のシェルスクリプト~/.gitconfigグローバルgitエイリアスとして直接に追加します。


マスターブランチのみを検索
Nasif Imtiaz Ohi

すべてのローカルブランチで検索
レオナルドエレーラ

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