就说我有个文件“HelloWorld.pm“在Git仓库的多个子目录中。
我想发出一个命令来查找所有匹配“www.example.com”的文件的完整路径HelloWorld.pm:
例如:
/path/to/repository/HelloWorld.pm
/path/to/repository/but/much/deeper/down/HelloWorld.pm
/path/to/repository/please/dont/make/me/search/through/the/lot/HelloWorld.pm
如何使用Git有效地找到与给定文件名匹配的所有完整路径?
我意识到我可以用Linux/Unix的find命令来做这件事,但我希望避免扫描所有的子目录来寻找文件名的示例。
7条答案
按热度按时间xytpbqjk1#
git ls-files
会给予你一个仓库(该高速缓存或索引)当前状态下所有文件的列表。您可以传入一个模式以获取与该模式匹配的文件。如果你想找到一组文件并通过grep浏览它们的内容,你可以使用
git grep
:ep6jt1vc2#
嗯,最初的问题是关于仓库的。一个仓库包含多于1个提交(至少在一般情况下),但是之前给出的答案只搜索一个提交。
因为我无法找到一个真正搜索整个提交历史的答案,我写了一个快速的暴力破解脚本git-find-by-name,它考虑了(几乎)所有的提交。
也许有更优雅的方式。
请注意,参数传递到grep的方式很简单,因此它将匹配filename的部分内容。如果不希望这样,则锚定搜索表达式和/或添加合适的grep选项。
对于深度历史,输出可能太嘈杂,我想到了一个脚本,它将修订列表转换为范围,就像git rev-list可以做的相反。但到目前为止,它仍然是一个想法。
ws51t4hk3#
尝试:
lo8azlld4#
grep -i使grep不区分大小写。
cu6pst1q5#
[It我承认,这有点滥用评论,但我还不能发表评论,我想我会改进@uwe-geuder的回答。
再一次,+1到@uwe-geuder获得一个很好的答案。
如果你对BASH本身感兴趣:
除非你保证在for循环中进行单词分割(比如使用这样的数组:
for item in "${array[@]}"
),我强烈建议在您循环的命令输出由换行符分隔时使用while IFS= read var ; do ... ; done < <(command)
(或在输出由空字符串$'\0'
分隔时使用read -d''
)。虽然git rev-list --all
保证使用40字节的十六进制字符串(没有空格),但我从不喜欢冒险。现在,我可以轻松地将命令从git rev-list --all
更改为生成行的任何命令我还建议使用内置的BASH机制来注入输入和过滤输出,而不是临时文件。
ulmd4ohb6#
Uwe Geuder(@uwe-geuder)编写的脚本很棒,但真的没有必要将每个ls-tree输出转储到自己的目录中,不进行过滤。
速度更快,使用更少的存储空间:对输出运行grep,然后存储它,如下面的gist所示:
vwhgwdsa7#
@Uwe-Geuder的代码可以做成一行程序
这也解决了硬盘泛洪问题。