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

问题描述 投票:0回答:6

是否可以在 Git 控件源项目的所有分支中运行

git grep
?或者还有其他命令可以运行吗?

git grep
6个回答
236
投票

问题“如何在 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. 在评论中推荐

我在尝试

fatal: bad flag '->' used after filename
版本时得到了“
git branch
”。该错误与
HEAD
别名符号相关。

我通过在管道中的

sed '/->/d'
tr
命令之间添加
xargs
来解决这个问题。

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>

这是对 chernjie 建议的解决方案的改进,因为

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>

100
投票

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

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

这些日志命令列出添加或删除给定搜索字符串/正则表达式的提交,(通常)首先是最近的。

-p
选项会导致在添加或删除模式的位置显示相关差异,以便您可以在上下文中看到它。

找到添加您要查找的文本的相关提交(例如 8beeff00d)后,找到包含该提交的分支:

git branch -a --contains 8beeff00d

34
投票

我发现这最有用(如果您需要区分大小写的搜索,请省略

-i
):

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/)'

9
投票

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

以下是三个命令:

  1. git grep-branch
    - 在本地和远程的所有分支机构中搜索
  2. git grep-branch-local
    - 仅在当地分行搜索
  3. git grep-branch-remote
    - 仅限远程分支

用法与

git grep
相同:

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

1. 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
    - 显示所有分支;
  • 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
将行号添加到匹配行的前缀。

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

2. 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"

4
投票

我是这样做的:

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

4
投票

如果您向

git grep
提供任何提交 SHA-1 哈希值,您将在其中搜索它,而不是工作副本。

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

所有
树。把它全部放在

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

...要有耐心

© www.soinside.com 2019 - 2024. All rights reserved.