这是一个适合我的解决方案。我已经在 git (log|diff) -G<regex> 选项上编写了解决方案和一些额外的缺失文档。
它基本上使用与先前答案相同的解决方案,但专门针对以* 或# 开头的cmets,有时* 之前有一个空格...但它仍然需要允许#ifdef、#include等变化。
-G 选项似乎不支持向前看和向后看,? 通常也不支持,而且我在使用 * 时也遇到了问题。不过,+ 似乎运作良好。
(注意,在 Git v2.7.0 上测试过)
多行注释版
git diff -w -G'(^[^\*# /])|(^#\w)|(^\s+[^\*#/])'
-
-w忽略空格
-
-G 仅显示匹配以下正则表达式的差异行
-
(^[^\*# /]) 任何不以星号、哈希或空格开头的行
-
(^#\w) 任何以 # 开头后跟一个字母的行
-
(^\s+[^\*#/]) 任何以空格开头后跟注释字符的行
基本上一个 SVN 钩子现在修改每个文件,并修改每个文件上的多行注释块。现在我可以将我的更改与 SVN 进行比较,而无需 SVN 在 cmets 中删除的 FYI 信息。
从技术上讲,这将允许 Python 和 Bash cmets(如 #TODO)显示在差异中,如果除法运算符在 C++ 中的新行开始,则可以忽略它:
a = b
/ c;
Git 中关于-G 的文档似乎也很缺乏,所以这里的信息应该会有所帮助:
git diff -G<regex>
-G<regex>
查找补丁文本包含与<regex>匹配的添加/删除行的差异。
为了说明-S<regex> --pickaxe-regex和-G<regex>之间的区别,
考虑在同一文件中提交具有以下差异的提交:
+ return !regexec(regexp, two->ptr, 1, ®match, 0);
...
- hit = !regexec(regexp, mf2.ptr, 1, ®match, 0);
虽然git log -G"regexec\(regexp" 将显示此提交,
git log -S"regexec\(regexp" --pickaxe-regex 不会
(因为该字符串的出现次数没有改变)。
请参阅gitdiffcore(7) 中的镐 条目了解更多信息。
(注意,在 Git v2.7.0 上测试过)
-
-G 使用基本的正则表达式。
- 不支持
?、*、!、{、} 正则表达式语法。
- 使用
() 进行分组和使用| 进行OR-ing 组。
- 支持
\s、\W等通配符。
-
不支持前瞻和后瞻。
- 开始和结束行锚
^$ 工作。
- 功能自 Git 1.7.4 起可用。
排除的文件 v 排除的差异
请注意,-G 选项会过滤将要进行比较的文件。
但是如果一个文件被“差异化”,那些之前被“排除/包含”的行将全部显示在差异中。
示例
仅显示至少有一行提及foo 的文件差异。
git diff -G'foo'
显示除以# 开头的行之外的所有内容的文件差异
git diff -G'^[^#]'
显示提及FIXME 或TODO 的不同文件
git diff -G`(FIXME)|(TODO)`
另请参阅git log -G、git grep、git log -S、--pickaxe-regex 和 --pickaxe-all
更新:-G 选项正在使用哪个正则表达式工具?
https://github.com/git/git/search?utf8=%E2%9C%93&q=regcomp&type=
https://github.com/git/git/blob/master/diffcore-pickaxe.c
if (opts & (DIFF_PICKAXE_REGEX | DIFF_PICKAXE_KIND_G)) {
int cflags = REG_EXTENDED | REG_NEWLINE;
if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE))
cflags |= REG_ICASE;
regcomp_or_die(®ex, needle, cflags);
regexp = ®ex;
// and in the regcom_or_die function
regcomp(regex, needle, cflags);
http://man7.org/linux/man-pages/man3/regexec.3.html
REG_EXTENDED
Use POSIX Extended Regular Expression syntax when interpreting
regex. If not set, POSIX Basic Regular Expression syntax is
used.
// ...
REG_NEWLINE
Match-any-character operators don't match a newline.
A nonmatching list ([^...]) not containing a newline does not
match a newline.
Match-beginning-of-line operator (^) matches the empty string
immediately after a newline, regardless of whether eflags, the
execution flags of regexec(), contains REG_NOTBOL.
Match-end-of-line operator ($) matches the empty string
immediately before a newline, regardless of whether eflags
contains REG_NOTEOL.