git 如何grep Git提交某个单词的差异或内容?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1337320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:56:50  来源:igfitidea点击:

How to grep Git commit diffs or contents for a certain word?

gitsearchgrep

提问by Jesper R?nn-Jensen

In a Git code repository I want to list all commits that contain a certain word. I tried this

在 Git 代码存储库中,我想列出包含某个单词的所有提交。我试过这个

git log -p | grep --context=4 "word"

but it does not necessarily give me back the filename (unless it's less that 5 lines away from the word I searched for. I also tried

但它不一定会给我回文件名(除非它与我搜索的词相差不到 5 行。我也试过

git grep "word"

but it gives me only present files and not the history.

但它只给我当前文件而不是历史。

How do I search the entire history so I can follow changes on a particular word? I intend to search my codebase for occurrences of word to track down changes (search in files history).

如何搜索整个历史记录,以便跟踪特定单词的变化?我打算在我的代码库中搜索单词的出现以跟踪更改(在文件历史记录中搜索)。

回答by Jakub Nar?bski

If you want to find all commits where commit messagecontains given word, use

如果要查找提交消息包含给定单词的所有提交,请使用

$ git log --grep=word

If you want to find all commits where "word" was added or removed in the file contents(to be more exact: where number of occurences of "word" changed), i.e. search the commit contents, use so called 'pickaxe' search with

如果要查找在文件内容中添加或删除了“word”的所有提交(更准确地说:“word”的出现次数已更改),即搜索提交内容,请使用所谓的“pickaxe”搜索

$ git log -Sword

In modern git there is also

在现代 git 中也有

$ git log -Gword

to look for differenceswhose added or removed line matches "word" (also commit contents).

查找添加或删除的行与“word”匹配的差异(也提交内容)。

Note that -Gby default accepts a regex, while -Saccepts a string, but can be modified to accept regexes using the --pickaxe-regex.

请注意,-G默认情况下接受正则表达式,而-S接受字符串,但可以使用--pickaxe-regex.

To illustrate the difference between -S<regex> --pickaxe-regexand -G<regex>, consider a commit with the following diff in the same file:

+    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

While git log -G"regexec\(regexp"will show this commit, git log -S"regexec\(regexp" --pickaxe-regexwill not (because the number of occurrences of that string did not change).

为了说明之间的区别-S<regex> --pickaxe-regex,并-G<regex>考虑在同一个文件中的以下DIFF提交:

+    return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

虽然git log -G"regexec\(regexp"会显示此提交,但git log -S"regexec\(regexp" --pickaxe-regex不会(因为该字符串的出现次数没有改变)。



With Git 2.25.1 (Feb. 2020), the documentation is clarified around those regexes.

在 Git 2.25.1(2020 年 2 月)中,文档围绕这些正则表达式进行了澄清。

See commit 9299f84(06 Feb 2020) by Martin ?gren (``).
(Merged by Junio C Hamano -- gitster--in commit 0d11410, 12 Feb 2020)

请参阅Martin ?gren (``) 的提交 9299f84(2020 年 2 月 6 日
(由Junio C gitsterHamano合并-- --commit 0d11410,2020 年 2 月 12 日)

diff-options.txt: avoid "regex" overload in example

Reported-by: Adam Dinwoodie
Signed-off-by: Martin ?gren
Reviewed-by: Taylor Blau

When we exemplify the difference between -Gand -S(using --pickaxe-regex), we do so using an example diff and git diffinvocation involving "regexec", "regexp", "regmatch", ...

The example is correct, but we can make it easier to untangle by avoiding writing "regex.*" unless it's really needed to make our point.

Use some made-up, non-regexy words instead.

diff-options.txt:在示例中避免“正则表达式”重载

报告人:Adam Dinwoodie
签字人:Martin ?gren
评论人:Taylor Blau

当我们举例说明-G-S(使用--pickaxe-regex)之间的区别时,我们使用一个示例差异和git diff涉及“regexec”、“regexp”、“regmatch”、...

这个例子是正确的,但我们可以通过避免编写“regex.*”来更容易地解开,除非它真的需要表达我们的观点。

改用一些虚构的、非正则化的词。

The git diffdocumentationnow includes:

git diff文档现在包括:

To illustrate the difference between -S<regex> --pickaxe-regexand -G<regex>, consider a commit with the following diff in the same file:

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

While git log -G"frotz\(nitfol"will show this commit, git log -S"frotz\(nitfol" --pickaxe-regexwill not (because the number of occurrences of that string did not change).

为了说明之间的区别-S<regex> --pickaxe-regex,并 -G<regex>考虑在同一个文件中的以下DIFF提交:

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);

虽然git log -G"frotz\(nitfol"会显示此提交,但git log -S"frotz\(nitfol" --pickaxe-regex不会(因为该字符串的出现次数没有改变)。

回答by u0b34a0f6ae

git log's pickaxe will find commits with changes including "word" with git log -Sword

git log's pickaxe 将查找包含更改的提交,包括“word” git log -Sword

回答by CharlesW

After a lot of experimentation, I can recommend the following, which shows commits that introduce or remove lines containing a given regexp, and displays the text changes in each, with colours showing words added and removed.

经过大量实验,我可以推荐以下内容,其中显示了引入或删除包含给定正则表达式的行的提交,并显示每个文本的更改,颜色显示添加和删除的单词。

git log --pickaxe-regex -p --color-words -S "<regexp to search for>"

Takes a while to run though... ;-)

虽然需要一段时间才能运行...... ;-)

回答by kenorb

You can try the following command:

您可以尝试以下命令:

git log --patch --color=always | less +/searching_string

or using grepin the following way:

grep以下列方式使用:

git rev-list --all | GIT_PAGER=cat xargs git grep 'search_string'

Run this command in the parent directory where you would like to search.

在要搜索的父目录中运行此命令。

回答by 1u-

One more way/syntax to do it is: git log -S "word"
Like this you can search for example git log -S "with whitespaces and stuff @/#ü !"

另一种方法/语法是:git log -S "word"
像这样你可以搜索例如git log -S "with whitespaces and stuff @/#ü !"

回答by Reudismam

To use boolean connector on regular expression:

在正则表达式上使用布尔连接器:

git log --grep '[0-9]*\|[a-z]*'

This regular expression search for regular expression [0-9]* or [a-z]* on commit messages.

此正则表达式在提交消息上搜索正则表达式 [0-9]* 或 [az]*。

回答by Lerner Zhang

vim-fugitiveis versatile for that kind of examining in Vim.

vim-fugitive对于在 Vim 中进行这种检查是通用的。

Use :Ggrepto do that. For more information you can install vim-fugitive and look up the turorial by :help Grep. And this episode: exploring-the-history-of-a-git-repositorywill guide you to do all that.

使用:Ggrep这样做。有关更多信息,您可以安装 vim-fugitive 并通过:help Grep. 而这一集:探索 git-repository 的历史将指导您完成所有这些。

回答by edelans

If you want search for sensitive data in order to remove it from your git history (which is the reason why I landed here), there are tools for that. Github as a dedicated help page for that issue.

如果您想搜索敏感数据以将其从您的 git 历史记录中删除(这就是我登陆这里的原因),有一些工具可以做到这一点。Github 作为该问题的专用帮助页面

Here is the gist of the article:

这是文章的要点:

The BFG Repo-Cleaneris a faster, simpler alternative to git filter-branch for removing unwanted data. For example, to remove your file with sensitive data and leave your latest commit untouched), run:

BFG回购清机是与git滤波器分支更快,更简单的替代用于去除不想要的数据。例如,要删除包含敏感数据的文件并保持最新提交不变),请运行:

bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

To replace all text listed in passwords.txt wherever it can be found in your repository's history, run:

要替换 passwords.txt 中所有可以在存储库历史记录中找到的所有文本,请运行:

bfg --replace-text passwords.txt

See the BFG Repo-Cleaner's documentationfor full usage and download instructions.

有关完整的使用和下载说明,请参阅BFG Repo-Cleaner 的文档