在Git中,我怎么能通过多个分支上的路径搜索文件或目录?现在,我需要找到它。

说明:我正在寻找在我的一个分支中创建的文件。我想按路径而不是按内容查找,因为我不记得内容是什么。

评论

我不清楚这个问题。该文件是否在现在已删除的分支中?文件被删除了吗?

#1 楼

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


也支持滚动:引号是必需的(至少在使用Bash shell的情况下),因此shell会将glob模式不变地传递给git,而不是扩展它(就像在Unix find上一样)。

评论


如果您知道某文件的确切路径,则此方法有效:例如,如果您需要在路径/文件名上进行正则表达式搜索,则可以使用ididak的答案。

–ShreevatsaR
2012-2-27在9:05

也支持滚动:git log --all-** / my_file.png

– webmat
2012年4月25日18:01



我用这个来解决一个稍微不同的问题。我试图找到我提交给特定分支的所有* .sql文件。所以我用了git log --grep ='branch'--author ='me'-* .sql。像魅力一样工作。 git版本1.7.11.1

–thepriebe
2012年9月17日下午22:57

注意gitk也支持globbing。 @webmat是一个很好的答案!如果要查看已在哪里删除/创建/ etc,可以使用git log --all --stat-** / my_file.png,这样就不必猜测是否要检查它了。从删除它的提交中。

– eacousineau
13-10-4在4:55



@webmat:我很乐意将有关globing的信息添加到答案中。感谢您提及它!

–sleske
2014年12月9日9:51

#2 楼

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


这样的好处是,您还可以使用正则表达式搜索文件名。

评论


一些希望有帮助的注释:(a)您可能想在“ git ls-tree”中添加“ -r”,以便即使在子目录中也可以找到该文件。 (b)第一行也许更巧妙的选择是使用“ git for-each ref”,例如“ for git中的分支for-each-ref --format =“%(refname)” refs / heads; do”(c)“ git ls-tree --name-only”将使输出整齐(d)值得一提的是,与Dustin解决方案相比,这样做有一个优势,即您不需要完全知道文件名-您可以通过匹配路径任何部分的正则表达式进行搜索

–马克·朗伊尔(Mark Longair)
2010-6-28 at 16:02

我将其包装在脚本中,以便您可以运行“ gitfind.sh ”;要点是gist.github.com/62d981890eccb48a99dc

–Handyman5
2011-09-19 17:12

请注意,这只会搜索本地分支机构。要搜索远程跟踪分支,请使用ref / remotes而不是ref / heads。要搜索所有内容(本地分支,远程跟踪分支和标签),只需使用refs /。

–sleske
13年4月23日在7:43

#3 楼

尽管ididak的响应非常酷,并且Handyman5提供了一个脚本来使用它,但我发现使用该方法有些局限。那么为什么不搜索所有提交呢?除此之外,有时您需要冗长的答复,而其他时候仅提交匹配项。这是这些选项的两个版本。将这些脚本放在您的路径上:


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



for branch in $(git rev-list --all)
do
  git ls-tree -r --name-only $branch | grep "" | 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可以修改该脚本以交替搜索所有提交,引用,引用/ heads,冗长等。

$ 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 ”了吗?我知道了,谢谢!

–伊利亚·林恩(Elijah Lynn)
2014年4月1日在20:41



我个人发现使用$(git branch | cut -c 3-)代替$(git rev-list --all)更加有用。我不在乎查找一堆提交,我在乎命名分支。

– Campadrenalin
14年7月14日在20:15

我还更改了脚本以使用$(git branch | cut -c 3-),因为所有提交的循环都太慢了。

– i4h
15-10-26在10:39

看到所有的大惊小怪,我值得为此创建一个仓库。 github.com/albfan/git-find-file。我有一些问题,可以随时提出更多建议或发送公关请求。

– albfan
15年10月28日在12:09

@lumbric在路径上的安装脚本可以直接使用,它具有git功能

– albfan
16年5月13日在14:09

#4 楼

您可以使用gitk --all并搜索“触摸路径”提交和您感兴趣的路径名。

评论


如前所述,使用gitk --all,然后在View |新视图,启用所有分支。然后设置您的搜索条件:倒数第二个字段中的文件名(带通配符)。最后:好的。

– MikeW
16年1月21日在15:20



#5 楼

复制并粘贴以使用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 ""; done; :'


这些命令将作为全局git别名直接向您的~/.gitconfig添加一些最小的Shell脚本。

评论


它仅在主分支中搜索

– Nasif Imtiaz Ohi
19年3月20日在17:30

它在所有本地分支机构中搜索

–莱昂纳多·埃雷拉(Leonardo Herrera)
20年6月12日在17:39

如何获得它来搜索所有本地和远程分支?

– rgvcorley
20-6-29在5:52

#6 楼

可以在以下位置找到用于Git存储库的find命令的相当不错的实现:

https://github.com/mirabilos/git-find