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

Is it possible to perform a 'grep search' in all the branches of a Git project?

是否可以在Git控件源项目的所有分支内运行git grep? 还是有另一个命令要运行?


问题"如何在git历史中grep(搜索)已提交的代码?"建议:

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

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

另一种形式是:

1
2
3
4
5
git rev-list --all | (
    while read revision; do
        git grep -F 'yourWord' $revision
    done
)

您可以在本文中找到更多示例:

I tried the above on one project large enough that git complained about the argument size, so if you run into this problem, do something like:

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

(请参阅本答案最后一节中的替代方案,如下)

如果您需要,请不要忘记这些设置:

1
2
3
4
# Allow Extended Regular Expressions
git config --global grep.extendRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true

这个别名也有帮助:

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

注意:chernjie建议git rev-list --all是一种矫枉过正。

A more refined command can be:

1
git branch -a | tr -d \* | xargs git grep <regexp>

Which will allow you to search only branches (including remote branches)

You can even create a bash/zsh alias for it:

1
2
alias grep_all="git branch -a | tr -d \* | xargs git grep"
grep_all <regexp>

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

I got a"fatal: bad flag '->' used after filename" when trying the git branch version. The error was associated with a HEAD aliasing notation.

I solved it by adding a sed '/->/d' in the pipe, between the tr and the xargs commands.

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

那是:

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


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

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

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

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

1
git branch -a --contains 8beeff00d


我发现这个最有用:

1
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)

我创建的别名如下所示:

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


它可以通过两种常见方式实现:Bash或Git别名

这是三个命令:

  • git grep-branch - 在本地和远程的所有分支机构中搜索
  • git grep-branch-local - 仅在本地分支机构中搜索
  • git grep-branch-remote - 仅限远程分支
  • 用法与git grep相同

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

    GREP使用:Git别名

    文件?/ .gitconfig

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

    1
    2
    3
    4
    [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 - 显示所有分支;
    • sed -e 's/[ \\*]*//' - 修剪空格(来自branch -a)和*(活动分支名称具有它);
    • grep -v -e '\\->' - 忽略复杂的名称,如remotes/origin/HEAD -> origin/master;
    • grep '^remotes' - 获取所有远程分支;
    • grep -v -e '^remotes' - 获取除远程分支以外的分支;

    示例git grep-branch-local -n getTastyCookies

    -n将行号前缀为匹配行。

    1
    2
    3
    4
    [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)

    目前的结构是:

    : - 分隔符

  • 分支:dev
  • 行号:53
  • 文件路径:modules/factory/getters.php
  • 匹配线:function getTastyCookies($user)
  • GREP使用:BASH

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

    仅限本地分支机构

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

    仅限远程分支

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

    本地和远程分支机构

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


    我是这样做的:

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


    如果您将任何提交SHA1提供给git grep,则可以在其中搜索,而不是工作副本。

    要搜索所有分支,您可以使用git rev-list --all获取所有树。全部用

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

    ......并且有耐心