301

我有一个 Git 存储库,其中很少有分支和悬空提交。我想在存储库中搜索所有此类提交以查找特定字符串。

我知道如何获取历史中所有提交的日志,但这些不包括分支或悬垂的 blob,只是 HEAD 的历史。我想把它们全部收集起来,找到一个放错地方的特定提交。

我也想知道如何在 Mercurial 中执行此操作,因为我正在考虑切换。

4

10 回答 10

339

你可以看到悬空提交git log -g

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones. 

因此,您可以这样做以在悬空的提交消息中查找特定字符串:

git log -g --grep=search_for_this

或者,如果要搜索特定字符串的更改,可以使用镐搜索选项“-S”:

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Git 1.7.4 将添加 -G 选项,允许您通过 -G<regexp> 来查找包含 <regexp> 的行何时被移动,而 -S 无法做到这一点。-S 只会告诉您包含字符串的总行数何时更改(即添加/删除字符串)。

最后,您可以使用 gitk 来可视化悬空提交:

gitk --all $(git log -g --pretty=format:%h)

然后使用它的搜索功能来查找放错位置的文件。所有这些工作都假设丢失的提交没有“过期”并且被垃圾收集,如果它悬空 30 天并且您使 reflogs 过期或运行使它们过期的命令,则可能会发生这种情况。

于 2009-04-14T08:53:11.847 回答
56

在 Mercurial 中,您用于hg log --keyword搜索提交消息中的关键字并hg log --user搜索特定用户。查看hg help log其他限制日志的方法。

于 2009-05-21T00:37:51.443 回答
25

除了使用or的Richq 答案之外:查看当前 git 维护者 Junio C Hamano 的以下博客文章git log -g --grep=<regexp>git grep -e <regexp> $(git log -g --pretty=format:%h)


概括

git grepgit log --grep都是面向行的,因为它们查找与指定模式匹配的行。

您可以使用git log --grep=<foo> --grep=<bar>(或git log --author=<foo> --grep=<bar>内部转换为 two --grep)来查找匹配一模式(隐式OR语义)的提交。

由于是面向行的,有用的AND语义是用于git log --all-match --grep=<foo> --grep=<bar>查找在某处同时具有第一行匹配和第二行匹配的提交。

您可以将git grep多个模式(所有必须使用-e <regexp>表单)与(--or这是默认设置)--and、、、--not和。对于 grep意味着该文件必须具有与每个替代项匹配的行。()--all-match

于 2009-04-17T10:11:39.070 回答
11

基于 rq 的回答,我发现这条线可以满足我的要求:

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

它将报告提交 ID、文件名并显示匹配的行,如下所示:

91ba969:testFile:this is a test

...是否有人同意将其包含在标准 git grep 命令中是一个不错的选择?

于 2010-05-26T22:59:15.787 回答
6

任何将引用作为参数的命令都将接受--all手册页中记录的选项git rev-list,如下所示:

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

因此,例如git log -Sstring --all将显示所有提及string并且可以从分支或标签访问的提交(我假设您的悬空提交至少用标签命名)。

于 2009-04-14T08:49:10.543 回答
6

使用 Mercurial,您可以

$ hg grep "search for this" [file...]

还有其他选项可以缩小搜索的修订范围。

于 2009-04-20T00:42:18.807 回答
2

不了解 git,但在 Mercurial 中,我只需将 hg log 的输出通过管道传输到一些 sed/perl/whatever 脚本,以搜索您要查找的任何内容。如果您愿意,您可以使用模板或样式自定义 hg log 的输出,以使其更易于搜索。

这将包括 repo 中的所有命名分支。Mercurial 没有像悬空的 blobs afaik 之类的东西。

于 2009-04-14T08:54:33.357 回答
1

如果你是 vim 用户,你可以安装 tig (apt-get install tig),然后使用 /,同样的命令在 vim 上搜索

https://blogs.atlassian.com/2013/05/git-tig/

于 2013-09-12T15:00:52.717 回答
1

要添加一个尚未提及的解决方案,我不得不说使用 gitg 的图形搜索框对我来说是最简单的解决方案。它将选择第一个匹配项,您可以使用 Ctrl-G 找到下一个匹配项。

于 2013-10-27T04:24:01.257 回答
1

git 中的一个命令,我认为查找字符串要容易得多:

git log --pretty=oneline --grep "string to search"

适用于 Git 2.0.4

于 2014-12-06T04:07:20.723 回答