使用 Git,我如何在所有分支中搜索字符串?

Posted

技术标签:

【中文标题】使用 Git,我如何在所有分支中搜索字符串?【英文标题】:Using Git, how could I search for a string across all branches? 【发布时间】:2011-11-01 08:28:14 【问题描述】:

使用 Git,我如何在所有本地分支的所有文件中搜索给定字符串?

GitHub 特定:是否可以在所有 GitHub 分支中执行上述搜索? (在我的远程 GitHub 存储库中有几个远程分支,理想情况下我不必为此搜索而关闭......)

【问题讨论】:

git-grep 可能是您正在寻找的,但我不确定您需要哪些选项... How to grep (search) committed code in the git history?的可能重复 【参考方案1】:

您可以在 Git 存储库上执行此操作:

git grep "string/regexp" $(git rev-list --all)

GitHub 高级搜索具有代码搜索能力:

代码搜索将查看 GitHub 上公开托管的所有代码。您还可以通过以下方式过滤:

语言:language: 存储库名称(包括用户名):repo: 文件路径:path:

【讨论】:

这确实不是最好的方法。它不控制传递给 git grep ... 的 git refs 的数量。看看其他答案,即使它被标记为已接受的答案,它们也比这个要好得多! 如果您可以为您的过滤器添加一个示例,那就太好了,例如path:,因为文档一目了然并不清楚在哪里应用此过滤器,我假设它在您的查询示例中的引号之前? 我怎样才能只列出分支名称。目前,它列出了所有包含该字符串的散列。 Github 搜索仅在主分支上。来自help.github.com/articles/searching-code:“只有默认分支被索引用于代码搜索。在大多数情况下,这将是主分支。” 嗨,我正在开发一种工具,可以使用以下命令在所有远程和本地存储库中进行搜索:github.com/GaetanoPiazzolla/git-search,如果您愿意,请查看。【参考方案2】:

如果你使用@manojlds Git grep 命令并得到错误:

-bash: /usr/bin/git: Argument list too long" 

那么你应该使用xargs:

git rev-list --all | xargs git grep "string/regexp"

另见How to grep (search) committed code in the Git history

【讨论】:

另外,这似乎更兼容其他类型的游戏机,如fishshell 谢谢!!!使用 ZSH,这在 @manojlds 命令给出了您提到的错误时有效!但是警告,对于历史悠久的大型回购,这可能需要很长时间。 如果您正在查看特定文件,您可以使用:git rev-list --all | xargs -J % git grep "string/rexexp" % -- filename。这将在% 出现位置插入的提交块上运行git grep【参考方案3】:

在许多情况下,git rev-list --all 可以返回大量提交,需要很长时间才能进行扫描。如果您不想搜索存储库历史中每个分支上的每个提交,而只想搜索所有分支提示,则可以将其替换为 git show-ref -s --heads。所以总的来说:

git grep "string" `git show-ref -s --heads`

或:

git show-ref -s --heads | xargs git grep "string"

提示:您可以将输出写入文件以在编辑器中查看:

nano ~/history.txt
git show-ref -s --heads | xargs git grep "search string here" >> ~/history.txt

【讨论】:

git show-ref --heads 列出哈希和引用名称,因此它(第二行)将搜索两次。所以git show-ref --heads | cut -d' ' -f2 更好,因为它只会列出参考名称。 我不敢相信这个问题已经被问了多少次了,但你是唯一一个得到正确答案的人。 git show-ref --heads -s 仅输出 SHA1 哈希。此外,如果有多个分支指向同一个提交,您将有重复。您可以使用sort -u 删除它们,例如git show-ref --heads -s | sort -u | xargs git grep ... 这是我添加到 bashrc 中的函数。希望对某人有所帮助:function gsearch git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 # last grep to keep grep color highlight 这应该是公认的答案。在所有分支中查找字符串但仅针对最新内容是一个非常常见的用例。【参考方案4】:

此处列出的解决方案存在一些问题(甚至被接受)。

您不需要列出所有哈希值,因为您会得到重复项。此外,这需要更多时间。

它建立在此基础上,您可以在多个分支 masterdev 上搜索字符串 "test -f /"

git grep "test -f /" master dev

相同
printf "master\ndev" | xargs git grep "test -f /"

就这样吧。

这会找到所有本地分支的提示的哈希值并仅在这些提交中搜索:

git branch -v --no-abbrev | awk -F' *' 'print $3' | xargs git grep "string/regexp"

如果您也需要在远程分支中搜索,请添加-a

git branch -a -v --no-abbrev | awk -F' *' 'print $3' | xargs git grep "string/regexp"

进一步:

# Search in local branches
git branch | cut -c3- | xargs git grep "string"

# Search in remote branches
git branch -r | cut -c3- | xargs git grep "string"

# Search in all (local and remote) branches
git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string"

# Search in branches, and tags
git show-ref | grep -v "refs/stash" | cut -d' ' -f2 | xargs git grep "string"

【讨论】:

至少所有分支中的搜索应该是:git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" 否则它将在文件列表中出现-> 符号,表示本地到远程分支的关系 这条评论,就在我的评论上方,是正确答案!这是唯一没有出错的。 有没有办法从中获取分支名称?【参考方案5】:

你可以试试这个:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches

【讨论】:

跨所有分支:git log --all -s"search_string" 以上需要大写S【参考方案6】:

按照@peter-mortensen & manojlds 的解决方案,我使用git for-each-ref 作为子命令来仅列出具有名称的分支。

git grep "string/regexp" $(git for-each-ref --format='%(refname:short)' refs/heads)

这实现了更好的可视化,只显示命名的分支并且每个分支只生成一个结果。

【讨论】:

以上是关于使用 Git,我如何在所有分支中搜索字符串?的主要内容,如果未能解决你的问题,请参考以下文章

在所有分支的一个文件中搜索字符串

如何对Git的分支进行管理

如何在 Git 1.7+ 中列出所有远程分支?

Git 在团队中的最佳实践--如何正确使用Git Flow

Git 在团队中的最佳实践--如何正确使用Git Flow

如何在 git 中获取所有本地和远程标签?