是否可以在 Git 项目的所有分支中执行“ grep 搜索”?

是否有可能在 Git 控件源项目的所有分支中运行 git grep?还是有其他命令要运行?

79890 次浏览

如果你给任何提交一个 SHA-1散列值到 git grep你有它在他们中搜索,而不是工作副本。

要搜索所有分支,可以使用 git rev-list --all获得 所有

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

要有耐心

如何在 git 历史记录中对提交的代码进行 grep (搜索) ?”推荐的问题是:

 git grep <regexp> $(git rev-list --all)

它搜索所有提交,其中应包括所有分支。

另一种形式是:

git rev-list --all | (
while read revision; do
git grep -F 'yourWord' $revision
done
)

你可以在 这篇文章中找到更多的例子:

我在一个足够大的项目上尝试了上面的方法,因为 git 抱怨参数的大小,所以如果遇到这个问题,可以这样做:

git rev-list --all | (while read rev; do git grep -e <regexp> $rev; done)

(见下面这个答案的最后一部分)

不要忘记这些设置,如果你想要的话:

# Allow Extended Regular Expressions
git config --global grep.extendedRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true

这个别名也有帮助:

git config --global alias.g "grep --break --heading --line-number"

2016年8月更新: R.M.在评论中提出建议

在尝试 git branch版本时,我得到了一个“ fatal: bad flag '->' used after filename”。这个错误与一个 HEAD别名符号有关。

我通过在管道中的 trxargs命令之间添加一个 sed '/->/d'来解决这个问题。

 git branch -a | tr -d \* | sed '/->/d' | xargs git grep <regexp>

那就是:

alias grep_all="git branch -a | tr -d \* | sed '/->/d' | xargs git grep"
grep_all <regexp>

这是一个改进的解决方案 姐姐建议,因为 git rev-list --all是一个过度杀伤。

一个更精确的命令可以是:

# Don't use this, see above
git branch -a | tr -d \* | xargs git grep <regexp>

它只允许您搜索分支(包括远程分支)

您甚至可以为它创建一个 bash/zsh 别名:

# Don't use this, see above
alias grep_all="git branch -a | tr -d \* | xargs git grep"
grep_all <regexp>

我发现这个最有用:

git grep -i foo `git for-each-ref --format='%(refname)' refs/`

您需要根据是否只想查看远程分支和本地分支来调整最后的参数,例如:

  • git grep -i foo $(git for-each-ref --format='%(refname)' refs/remotes)
  • git grep -i foo $(git for-each-ref --format='%(refname)' refs/heads)

我创建的化名是这样的:

grep-refs = !sh -c 'git grep "$0" "$@" "$(git for-each-ref --format=\"%(refname)\"" refs/)'

git log可以是跨所有分支搜索文本的更有效的方法,特别是在有许多匹配项的情况下,并且您希望首先看到更新的(相关的)更改。

git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'

这些日志命令列表首先提交添加或删除给定搜索字符串/正则表达式(通常是最近的)。-p选项使相关的差异显示在模式被添加或删除的位置,因此您可以在上下文中看到它。

找到一个相关的提交来添加您正在寻找的文本(例如8beeff00d) ,找到包含提交的分支:

git branch -a --contains 8beeff00d

我是这么做的:

git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM

有两种常见的方法可以做到这一点: Bash 或 Git 别名

这里有三个命令:

  1. git grep-branch-搜索本地和远程的所有分支机构
  2. git grep-branch-local-只在本地分支机构搜索
  3. 只有远程分支

用法与 git grep相同

git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"

GREP 使用: Git 别名

文件 ~/. gitconfig

命令应该手动添加到 ~/.gitconfig文件中,因为 git config --global alias评估您添加的复杂代码并将其搞乱。


[alias]
grep-branch        = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | xargs git grep $@; };f "
grep-branch-remote = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | grep '^remotes' | xargs git grep $@; };f"
grep-branch-local  = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' -e '^remotes' | xargs git grep $@;  };f "

注意: 当您添加别名时,它们无法运行检查反斜杠 \,与 Bash命令相比,它们可能需要额外的转义 \\

  • git branch -a-显示所有分支;
  • 修剪 空间(从 branch -a)和 * (活动分支名称有它) ;
  • 忽略像 remotes/origin/HEAD -> origin/master这样复杂的名字;
  • 获取所有远程分支;
  • 获取分支 除了远程分支;

例子 git grep-branch-local -n getTastyCookies

将行号前缀为匹配的行。

[user@pc project]$ git grep-branch-local -n getTastyCookies


dev:53:modules/factory/getters.php:function getTastyCookies($user);
master:50:modules/factory/getters.php:function getTastyCookies($user)

目前的结构是:

:-分离器

  1. 分公司: dev
  2. 线路号码: 53
  3. 文件路径: modules/factory/getters.php
  4. 配对线路: function getTastyCookies($user)

GREP 使用: BASH

您应该知道: Bash 命令应该存储在 .sh脚本中,或者在 shell 中运行。

只有本地分行

git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' -e '^remotes' | xargs git grep "TEXT"

只有远程分支

git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | grep '^remotes' | xargs git grep "TEXT"

本地及远端分行

git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | xargs git grep "TEXT"