git diff:忽略某些正则表达式的删除或插入
git diff: ignore deletion or insertion of certain regex
如果添加或删除了以下表达式,我正在尝试使用 git diff
查找特定文件类型的两个版本之间的差异:
(****)
根据 the git diff Documentation,参数 -G
就是我要查找的内容。所以我尝试了以下方法:
git diff -G '\(\*\*\*\*\)' -- *.fileEnding
不幸的是,它不起作用,文件中的所有其他差异也被返回。顺便说一句,我对正则表达式不是很熟悉。
编辑:我认为我的问题需要更具体一些:现在我有以下情况:一个文件有与正则表达式匹配的更改和不匹配的更改。在我的脚本中,我试图做这样的事情(伪代码):
if((git diff -G '\(\*\*\*\*\)' -- *.fileEnding)==(git diff -- *.fileEnding)) print "Only changes in (****)";
如果某些文件仅在 (****) 中有更改而其他文件有不同的更改,则工作正常。但是一旦一个文件同时具有两者就不起作用
TL;DR
Git 的 git diff
不会那样做。
详细解释
文档具有误导性。
-G
参数对 git diff
完全没有任何作用。相反,-G
实际上是 git log
的参数(及其姊妹命令 git rev-list
,以及任何调用这些其他命令的命令;但最好只是根据 git log
,我想)。
git diff
和 git log
命令 分享 他们的一些文档(足够合理——他们分享他们的一些代码,特别是差异生成代码git log
用来将任何一个提交与其父项进行比较。
当 git log
正在 select 提交时,您可以告诉它 select 一些 特定的 提交(在 selection 已经由修订说明符制作)。 -G
论点就是这样一个 selector,非常相似的 -S
论点也是如此。 -S
默认接受字符串,而不是正则表达式;但您可以添加 --pickaxe-regex
以使 -S
采用正则表达式。文档有例子,例子字面上直接引用git log
:
-G<regex>
Look for differences whose patch text contains added/removed lines
that match <regex>.
To illustrate the difference between -S<regex> --pickaxe-regex
and
-G<regex>
, consider a commit with the following diff in the same file:
+ return !regexec(regexp, two->ptr, 1, ®match, 0);
...
- hit = !regexec(regexp, mf2.ptr, 1, ®match, 0);
While git log -G"regexec\(regexp"
will show this commit,
git log -S"regexec\(regexp" --pickaxe-regex
will not (because the number of occurrences of that string did not change).
git diff
命令不是 git log
命令。
一般来说,git log
的工作方式是向它传递一个起始提交——例如哈希 ID,或者分支或标签名称——然后它:
- 显示提交,然后
- 显示该提交的父项,然后
- 显示父项的父项 ...
等等,一直回到第一次提交(或者当你厌倦了查看并退出寻呼机时)。也就是说,至少对于这些简单的情况,存在一个循环:
while (there is a commit $commit)
parent = resolve_hash_id($commit + "^")
show($commit)
commit = $parent
如果添加 -p
,"show" 步骤包括 git diff $parent $commit
的输出。
请注意 git diff
比较 恰好两个 提交(好吧,有一种特殊的差异称为 组合差异 对于合并提交,但 git log
默认情况下不显示它们, git diff
的正常使用也不显示它们)。 git log
的两个提交是父项和子项。如果你 运行 git diff
自己,你可以选择任意两个提交......但是当你这样做时,git diff
完全忽略任何 -G
或 -S
个参数。(它可能应该抱怨它们的存在。)
-G
和-S
的重点是影响[=16=]的正常行为。通常,当我们按照 git log
的方式一次查看一个提交时,我们更感兴趣的是 特定更改 到 特定文件(或一组文件)。我们可以使用 -G
或 -S
告诉 git log
: 生成差异,但是如果没有变化,则根本不显示提交. 这样我们就只会看到那些有这些变化的提交。 (添加文件名,例如 git log stop..start -- path/to/file1.txt
,也将差异限制在这些文件上。与 -S
和 -G
不同,that 部分 和 git diff
一起工作吗。)
你能做什么
如果您不知道要进行哪些修订,可以使用git log
(或其面向脚本的姊妹命令git rev-list
)来筛选候选人。在这里,您可以使用-G
。您不必现在就获得差异,但如果您愿意,也可以。如果 -G
不仅让你得到 可能的 候选人,而且实际上让你得到 正确的 候选人,你就完成了,你可以停止这里。
如果您仍然有太多候选者并且需要完整的差异来进一步减少它们,您现在可以 运行 git diff
在第一步获得的哈希 ID 上(git log
或 git rev-list
)。对于这些提交中的每一个,您必须选择与哪个提交进行比较:可能是候选列表中的某个提交,或者可能是在这个特定候选之前或之后的提交。现在您不再拥有 -G
工具:要搜索差异,您将需要一些外部搜索工具,例如 grep
。这部分由你来写。
公认的答案是 -G
不适用于 git diff
,这是错误的。它绝对是:
git diff -G '\(\*\*\*\*\)'
将在数百个更改的文件中,return 只有具有 (****)
的文件作为其更改之一。
最初的发布者(我认为)承认了这一点,但不想在同一文件中看到其他更改。值得澄清的是 git diff
确实有 -G
并且它可以完成困难的部分(使用 git 2.20.1 测试)。使用 -G
仅显示更改的文件并使用 grep 仅显示这些文件中需要的部分将导致很少的误报:
git diff -G '\(\*\*\*\*\)' -- *yml | grep -n1 '(\*\*\*\*)'
将仅显示文本 (****)
已更改的行,以及一些上下文(足以看出它已更改为什么)。
另请参阅 以了解 -G
与差异的使用。
如果添加或删除了以下表达式,我正在尝试使用 git diff
查找特定文件类型的两个版本之间的差异:
(****)
根据 the git diff Documentation,参数 -G
就是我要查找的内容。所以我尝试了以下方法:
git diff -G '\(\*\*\*\*\)' -- *.fileEnding
不幸的是,它不起作用,文件中的所有其他差异也被返回。顺便说一句,我对正则表达式不是很熟悉。
编辑:我认为我的问题需要更具体一些:现在我有以下情况:一个文件有与正则表达式匹配的更改和不匹配的更改。在我的脚本中,我试图做这样的事情(伪代码):
if((git diff -G '\(\*\*\*\*\)' -- *.fileEnding)==(git diff -- *.fileEnding)) print "Only changes in (****)";
如果某些文件仅在 (****) 中有更改而其他文件有不同的更改,则工作正常。但是一旦一个文件同时具有两者就不起作用
TL;DR
Git 的 git diff
不会那样做。
详细解释
文档具有误导性。
-G
参数对 git diff
完全没有任何作用。相反,-G
实际上是 git log
的参数(及其姊妹命令 git rev-list
,以及任何调用这些其他命令的命令;但最好只是根据 git log
,我想)。
git diff
和 git log
命令 分享 他们的一些文档(足够合理——他们分享他们的一些代码,特别是差异生成代码git log
用来将任何一个提交与其父项进行比较。
当 git log
正在 select 提交时,您可以告诉它 select 一些 特定的 提交(在 selection 已经由修订说明符制作)。 -G
论点就是这样一个 selector,非常相似的 -S
论点也是如此。 -S
默认接受字符串,而不是正则表达式;但您可以添加 --pickaxe-regex
以使 -S
采用正则表达式。文档有例子,例子字面上直接引用git log
:
-G<regex>
Look for differences whose patch text contains added/removed lines that match <regex>.
To illustrate the difference between
-S<regex> --pickaxe-regex
and-G<regex>
, consider a commit with the following diff in the same file:+ return !regexec(regexp, two->ptr, 1, ®match, 0); ... - hit = !regexec(regexp, mf2.ptr, 1, ®match, 0);
While git log -G"regexec\(regexp"
will show this commit,git log -S"regexec\(regexp" --pickaxe-regex
will not (because the number of occurrences of that string did not change).
git diff
命令不是 git log
命令。
一般来说,git log
的工作方式是向它传递一个起始提交——例如哈希 ID,或者分支或标签名称——然后它:
- 显示提交,然后
- 显示该提交的父项,然后
- 显示父项的父项 ...
等等,一直回到第一次提交(或者当你厌倦了查看并退出寻呼机时)。也就是说,至少对于这些简单的情况,存在一个循环:
while (there is a commit $commit)
parent = resolve_hash_id($commit + "^")
show($commit)
commit = $parent
如果添加 -p
,"show" 步骤包括 git diff $parent $commit
的输出。
请注意 git diff
比较 恰好两个 提交(好吧,有一种特殊的差异称为 组合差异 对于合并提交,但 git log
默认情况下不显示它们, git diff
的正常使用也不显示它们)。 git log
的两个提交是父项和子项。如果你 运行 git diff
自己,你可以选择任意两个提交......但是当你这样做时,git diff
完全忽略任何 -G
或 -S
个参数。(它可能应该抱怨它们的存在。)
-G
和-S
的重点是影响[=16=]的正常行为。通常,当我们按照 git log
的方式一次查看一个提交时,我们更感兴趣的是 特定更改 到 特定文件(或一组文件)。我们可以使用 -G
或 -S
告诉 git log
: 生成差异,但是如果没有变化,则根本不显示提交. 这样我们就只会看到那些有这些变化的提交。 (添加文件名,例如 git log stop..start -- path/to/file1.txt
,也将差异限制在这些文件上。与 -S
和 -G
不同,that 部分 和 git diff
一起工作吗。)
你能做什么
如果您不知道要进行哪些修订,可以使用git log
(或其面向脚本的姊妹命令git rev-list
)来筛选候选人。在这里,您可以使用-G
。您不必现在就获得差异,但如果您愿意,也可以。如果 -G
不仅让你得到 可能的 候选人,而且实际上让你得到 正确的 候选人,你就完成了,你可以停止这里。
如果您仍然有太多候选者并且需要完整的差异来进一步减少它们,您现在可以 运行 git diff
在第一步获得的哈希 ID 上(git log
或 git rev-list
)。对于这些提交中的每一个,您必须选择与哪个提交进行比较:可能是候选列表中的某个提交,或者可能是在这个特定候选之前或之后的提交。现在您不再拥有 -G
工具:要搜索差异,您将需要一些外部搜索工具,例如 grep
。这部分由你来写。
公认的答案是 -G
不适用于 git diff
,这是错误的。它绝对是:
git diff -G '\(\*\*\*\*\)'
将在数百个更改的文件中,return 只有具有 (****)
的文件作为其更改之一。
最初的发布者(我认为)承认了这一点,但不想在同一文件中看到其他更改。值得澄清的是 git diff
确实有 -G
并且它可以完成困难的部分(使用 git 2.20.1 测试)。使用 -G
仅显示更改的文件并使用 grep 仅显示这些文件中需要的部分将导致很少的误报:
git diff -G '\(\*\*\*\*\)' -- *yml | grep -n1 '(\*\*\*\*)'
将仅显示文本 (****)
已更改的行,以及一些上下文(足以看出它已更改为什么)。
另请参阅 -G
与差异的使用。