我曾经删除过一个文件或文件中的一些代码。我可以在内容(而不是提交消息)中进行grep吗?

一个非常糟糕的解决方案是grep日志:

git log -p | grep <pattern>

然而,这不会立即返回提交哈希。我和吉特·格里普玩得不亦乐乎。


当前回答

为了简单起见,我建议使用GUI:gitk——Git存储库浏览器。它很灵活

要搜索代码:要搜索文件,请执行以下操作:当然,它还支持正则表达式:

您可以使用向上/向下箭头浏览结果。

其他回答

对于其他试图在Sourcetree中执行此操作的用户,UI中没有直接命令(从1.6.21.0版起)。但是,您可以通过打开终端窗口(主工具栏中可用的按钮)并将其复制/粘贴到其中来使用接受答案中指定的命令。

注意:Sourcetree的“搜索”视图可以部分为您进行文本搜索。按Ctrl+3转到“搜索”视图(或单击底部可用的“搜索”选项卡)。从最右边开始,将“搜索类型”设置为“文件更改”,然后键入要搜索的字符串。与上述命令相比,此方法具有以下限制:

Sourcetree只显示其中一个已更改文件中包含搜索词的提交。查找包含搜索文本的确切文件也是一项手动任务。不支持RegEx。

所以,您是否正在尝试翻看旧版本的代码,以查看最后存在的内容?

如果我这样做的话,我可能会使用git平分。使用平分线,您可以指定已知的好版本、已知的坏版本,以及一个简单的脚本,该脚本可以检查版本是好还是坏(在本例中,一个grep可以查看您正在查找的代码是否存在)。运行此命令将发现代码何时被删除。

要搜索提交内容(即实际的源代码行,而不是提交消息等),您需要执行以下操作:

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

git rev list--如果遇到“Argument list too long”错误,则所有|xargs git grep<expression>都可以工作。

如果要将搜索限制在某个子树(例如,“lib/util”),则需要将其传递给rev-list子命令和grep:

git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util

这将快速浏览正则表达式的所有提交文本。

在两个命令中传递路径的原因是rev-list将返回对lib/util所做的所有更改所在的修订列表,但您还需要传递给grep,以便它只在lib/util中搜索。

想象一下下面的场景:grep可能会在rev列表返回的同一版本中包含的其他文件上找到相同的<regexp>(即使该版本中的文件没有更改)。

以下是搜索源的一些其他有用方法:

在工作树中搜索与正则表达式正则表达式匹配的文本:

git grep <regexp>

在工作树中搜索与正则表达式regexp1或regexp2匹配的文本行:

git grep -e <regexp1> [--or] -e <regexp2>

在工作树中搜索与正则表达式regexp1和regexp2匹配的文本行,仅报告文件路径:

git grep -l -e <regexp1> --and -e <regexp2>

在工作树中搜索具有匹配正则表达式regexp1的文本行和匹配正则表达式表达式regexp2的文本行的文件:

git grep -l --all-match -e <regexp1> -e <regexp2>

在工作树中搜索已更改的文本匹配模式行:

git diff --unified=0 | grep <pattern>

搜索与正则表达式正则表达式匹配的文本的所有修订:

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

搜索rev1和rev2之间的所有修订,以查找与正则表达式regexp匹配的文本:

git grep <regexp> $(git rev-list <rev1>..<rev2>)

在任何版本、任何文件(Unix/Linux)中搜索:

git rev-list --all | xargs git grep <regexp>

仅在某些给定文件中搜索,例如XML文件:

git rev-list --all | xargs -I{} git grep <regexp> {} -- "*.xml"

结果行应如下所示:6988bec26b1503d45eb0b2e8a4364afb87dde7af:bla.xml:找到的行的文本。。。

然后,您可以使用gitshow获取更多信息,如作者、日期和差异:

git show 6988bec26b1503d45eb0b2e8a4364afb87dde7af

A.完整、唯一、排序的路径:

# Get all unique filepaths of files matching 'password'
# Source: https://stackoverflow.com/a/69714869/10830091
git rev-list --all | (
    while read revision; do
        git grep -F --files-with-matches 'password' $revision | cat | sed "s/[^:]*://"
    done
) | sort | uniq

B.唯一、排序的文件名(不是路径):

# Get all unique filenames matching 'password'
# Source: https://stackoverflow.com/a/69714869/10830091
git rev-list --all | (
    while read revision; do
        git grep -F --files-with-matches 'password' $revision | cat | sed "s/[^:]*://"
    done
) | xargs basename | sort | uniq

第二个命令对BFG很有用,因为它只接受文件名,而不接受相对/系统绝对路径。

在这里查看我的完整答案以了解更多解释。