如何通过提交信息在Git仓库中搜索?

1218

我已经通过提交信息"Build 0051"将一些源代码检入GIT中。

然而,我似乎无法再找到那些源代码了——我该如何使用命令行从GIT存储库中提取这些源代码?

更新

  1. 使用SmartGIT检入版本0043、0044、0045和0046。
  2. 检出0043,在不同的分支上检入版本直到0051。
  3. 重新检出0043。
  4. 现在,0051已经消失了。

更新

源代码确实存在,现在只需要检出它:

C:\Source>git log -g --grep="0052"
commit 77b1f718d19e5cf46e2fab8405a9a0859c9c2889
Reflog: HEAD@{10} (unknown <Mike@.(none)>)
Reflog message: commit: 20110819 - 1724 - GL: Intermediate version. File version:  v0.5.0 build 0052.
Author: unknown <Mike@.(none)>
Date:   Fri Aug 19 17:24:51 2011 +0100

    20110819 - 1724 - GL: Intermediate version. File version: v0.5.0 build 0052.

C:\Source>

1
请参见https://dev59.com/-WMl5IYBdhLWcg3wyJfz。 - ripper234
可能是重复的问题:如何在git提交中使用grep查找特定单词 - user456814
13个回答

1821

搜索包含给定文本的提交日志(跨所有分支):

git log --all --grep='Build 0051'

在grep搜索时忽略大小写,可以这样做:

git log --all -i --grep='Build 0051'

要搜索存储库历史记录中的提交实际内容,请使用:

git grep 'Build 0051' $(git rev-list --all)

要显示给定文本的所有实例,包括文件名和提交 sha1。

如果要在忽略大小写的情况下执行此操作,请使用:

git grep -i 'Build 0051' $(git rev-list --all)

请注意,这将在每个阶段搜索提交的整个内容,而不仅仅是diff更改。要仅搜索diff更改,请使用以下之一:

git log -S[searchTerm]
git log -G[searchTerm]

最后,如果你的提交没有任何历史记录,则可以使用-g标志(代表--walk-reflogs)搜索引用日志本身作为最后的手段:

git log -g --grep='Build 0051'

编辑:如果你似乎丢失了历史记录,请检查 reflog 以备不时之需。在列出的提交中寻找 Build 0051。

git reflog
你可能只是将你的HEAD设置到历史记录中未显示“Build 0051”提交的部分,或者你可能已经丢失了这个提交。 可以参考Git Ready reflog文章来解决问题。从reflog中恢复你的提交:找到你发现的提交并使用git checkout命令检出它(可选择为其创建新分支或标签方便以后查看)。
git checkout 77b1f718d19e5cf46e2fab8405a9a0859c9c2889
# alternative, using reflog (see git-ready link provided)
# git checkout HEAD@{10}
git checkout -b build_0051 # make a new branch with the build_0051 as the tip

3
使用命令 git grep 'Build 0051' $(git rev-list --all) 时,我得到了 "sh.exe": /bin/git: Bad file number 的错误信息,也许执行方法已经改变了吗? - Jens Schauder
9
查询git日志时使用的命令为:git log -i -grep。 - jhvaras
如果你在使用 git grep 'search' $(git rev-list --all) 时遇到错误,可以尝试使用 git rev-list --all | xargs git grep 'search' - afilina
3
在Windows上,我必须使用双引号而不是单引号才能使这个工作。 - esteuart
@shelhamer,“git log --all --grep ='Build 0051'”和“git grep 'Build 0051' $(git rev-list --all)”有什么区别? - John

111

我把以下内容放在了~/.gitconfig中:

[alias]
    find = log --pretty=\"format:%Cgreen%H %Cblue%s\" --name-status --grep

那么我可以输入"git find string",然后得到包含该字符串的所有提交信息的列表。例如,要查找引用票号#33的所有提交:

029a641667d6d92e16deccae7ebdeef792d8336b Added isAttachmentEditable() and isAttachmentViewable() methods. (references #33)
M       library/Dbs/Db/Row/Login.php

a1bccdcd29ed29573d2fb799e2a564b5419af2e2 Add permissions checks for attachments of custom strategies. (references #33).
M       application/controllers/AttachmentController.php

38c8db557e5ec0963a7292aef0220ad1088f518d Fix permissions. (references #33)
M       application/views/scripts/attachment/_row.phtml

041db110859e7259caeffd3fed7a3d7b18a3d564 Fix permissions. (references #33)
M       application/views/scripts/attachment/index.phtml

388df3b4faae50f8a8d8beb85750dd0aa67736ed Added getStrategy() method. (references #33)
M       library/Dbs/Db/Row/Attachment.php

3
不错,但是可能缺少一个颜色重置吗? --pretty=\"format:%Cgreen%H %Cblue%s%Creset\" - Ashley Coolman
12
我更喜欢打印完整的git信息(可能会在其中使用grep,而不是标题),因此我最终得出:find = log --all --pretty=\"format:%Cgreen%H %Cblue%s\n%b%Creset\" --name-status --grep。请注意 --all%b 字符。感谢@AshleyCoolman的reset提示。 - arcol
12
谢谢。我发现这个别名非常有用。我不喜欢着色,发现一行格式对此非常完美。同时添加 -i 以使其不区分大小写也很有帮助。例如:find = log --oneline --name-status -i --grep - robbp

71

虽然有点晚了,但是现在有了专门用于根据提交消息指定提交(或修订版本)的标记:/,只需在搜索字符串前加上:/即可。例如:

git show :/keyword(s)

这里的<keywords>可以是单个单词,也可以是由空格组成的复杂正则表达式模式,因此请在必要时进行引用/转义,例如:

git log -1 -p ":/a few words"

或者,可以指定一个起点,以查找从特定点可达的最近提交,例如:

git show 'HEAD^{/fix nasty bug}'

参见:Git修订手册


1
酷,我不知道这个!现在我该如何使用这个符号获取父提交?通常的“^”似乎不起作用。 - LoneCodeRanger
1
很简单 :-) 你只需要用两个git命令来完成,例如 git rev-parse $(git rev-parse :/keyword)~ @AndreiToroplean - ryenus

36
git log --grep="Build 0051"

这应该会奏效


2
必须使用双引号(")而不是单引号(')。 - frage

31
git log --grep=<pattern>
            Limit the commits output to ones with log message that matches the
            specified pattern (regular expression).

18

试试这个!

git log | grep -b3 "Build 0051"

7
建议使用 git grep 替代普通的 grep,并添加 --all 标志以搜索多个分支。 - shelhamer
1
嗯 - 其他答案也找不到吗?如果是这样,你可能有更大的问题。我建议尝试使用 git log --all --grep='Build 0051'(@shelhamer的答案)。 - Nic
我尝试了"git log --all",它只列出了版本到0046。版本0051在另一个分支上。我回滚到了0043,0051消失了。 - Contango
听起来好像你回滚时丢失了历史记录? - Nic
3
@Gravitas,可以尝试使用我的示例,其中包含git log -g命令。如果您在重置中丢失了历史记录,但是如果它还没有被垃圾回收,您仍然可以检查reflog。 - shelhamer
显示剩余2条评论

10

对于git log --all --grep命令,只需进行小幅添加: 在我这种情况下,我必须转义消息内的括号:

git log --all --grep="\[C\] Ticket-1001: Fix nasty things"

2
找到提交后,您可能想要找到它所在的分支:git branch -a --contains <hash>(感谢 https://dev59.com/kXE85IYBdhLWcg3wl0jF#2707110) - Charles L.

8

首先列出提交使用

git log --oneline

然后找到提交的SHA(消息), 然后我使用了

 git log --stat 8zad24d

(8zad24d)是与您感兴趣的提交相关联的SHA(例如,您可以选择4个字符、6个字符、8个字符或整个SHA),以查找正确的信息。


8
要搜索所有分支
git log --all --grep='Build 0051'

一旦你知道你想要达到哪个提交

git checkout <the commit hash>

6

不起作用。显示所有先前的提交。 - AG_HIHI

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