在多个Git仓库中搜索内容

13

我从其他开发者那里继承了一个相当大的代码库,代码存储在各种 git 存储库中。

有时候,很难知道某个特定代码片段可能位于哪个项目中,或者这段代码是否存在于 git 中。

我想要做的是在所有项目中搜索特定的文本。

我正在使用 gitosis,因此所有 git 存储库都存储在 /home/git/repositories 中,并且具有如下结构:

/home/git/repositories
  |- project1
    |- HEAD
    |- branches
    |- config
    |- description
    |- hooks
    |- info
    |- objects
    |- refs
  |- project2
    |- ...

我尝试着使用递归grep查找对象目录中的内容,代码如下:

grep -Hr "text" /home/git/repositories/*/objects

这当然没有按照我的意图工作,因为对象以git的自定义格式存储。

该怎么办?

3个回答

10

使用带有参考或--no-indexgit grep命令:

cd /home/git/repositories
for i in *; do ( cd $i; git grep text HEAD ); done

如果您正在寻找特定的代码段,而不是提交消息中的文本,您也可以在此处使用 git log -S"<string>"。它被称为 pickaxe 搜索 - Christopher
问题在于/home/git/repositories中的文件夹实际上不是git工作树,因此无法在它们上面使用git grep。 - jdeuce
@python_noob 如果您指定了一个引用(例如HEAD),则git grep在裸仓库中可以工作。 - William Pursell
1
好吧,这真令人沮丧。我刚刚在寻找一种比简单的 shell 包装器更好的方法来完成这个任务,但我发现唯一的答案是我自己 7 年前写的!现在肯定有更好的工具了吧! - William Pursell
我已经提交了一个功能请求:https://public-inbox.org/git/MN2PR11MB3663C042590097D7A7F4B2409DF10@MN2PR11MB3663.namprd11.prod.outlook.com/ - Ed Avis

5

虽然这是一个老问题,但如果您使用命令行,可以将此添加到bash_profilebashrc中。

ggrep() {
    find . -type d -name .git | while read line; do
        (
        cd $line/..
        cwd=$(pwd)
        echo "$(tput setaf 2)$cwd$(tput sgr0)"
        git grep -n "$@"
        )
    done
}

以上函数的基本要点是搜索包含.git的所有目录,并输出第一个包含该令牌的目录及文件及其行号。
然后进入/home/git/repositories并使用以下命令进行搜索: ggrep "InvalidToken" 它会输出如下结果:
/home/git/org/repo1
/home/git/org/repo2
/home/git/org/repo3
/home/git/org/repo3
lib/v3/Utility.pm:59:         code              => 'InvalidToken',
lib/v3/Utility.pm:142:        code              => "InvalidToken",

您还可以传递标志,例如 ggrep -i "search" (用于不区分大小写的搜索)


1
不错的解决方案。我的使用经验中有一个观察结果,因为我知道存储库都是当前文件夹的直接子代,所以我将“-maxdepth 2”添加到“find”命令的参数中,这使得执行速度更快。 - Quintin Willison
1
我不得不添加 --no-pager 以查看输出,就像这个答案中描述的那样(一次性查看所有结果文件夹而不是逐个查看)。 - Grygorii Iermolenko

2
使用multi。它是专门为同时在多个存储库中使用git grep而编写的。
$ ls
vim spring-framework gradle phantomjs
$ multi -i "fantastic"
vim
====================================================
runtime/doc/quotes.txt:VIM 4.5 is really a fantastic editor.  It has sooooo many features and more
runtime/doc/quotes.txt:fantastic it is! (Tony Nugent, Australia)
spring-framework
====================================================
gradle
====================================================
subprojects/docs/src/docs/userguide/ant.xml:        simply by relying on Groovy, and the fantastic <literal>AntBuilder</literal>.
subprojects/docs/src/docs/userguide/buildScriptsTutorial.xml:            relying on Groovy. Groovy is shipped with the fantastic <literal>AntBuilder</literal>. Using Ant tasks
subprojects/docs/src/docs/userguide/ideSupport.xml:            if you do this you have a fantastic IDE support for developing Gradle scripts. Of course if you use
phantomjs
====================================================
test/ghostdriver-test/fixtures/common/macbeth.html:<A NAME=1.3.55>Are ye fantastical, or that indeed</A><br>
test/ghostdriver-test/fixtures/common/macbeth.html:<A NAME=1.3.148>My thought, whose murder yet is but fantastical,</A><br>

在2021年,Multi仍然是这种用例的绝佳工具。 - nonbeing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接