git - 如何让 'git diff'忽略评论

标签 git diff git-diff

我正在尝试生成在特定提交中更改的文件列表。问题是,每个文件在文件顶部的注释中都有版本号 - 由于此提交引入了新版本,这意味着每个文件都已更改

我不关心更改的注释,所以我想让 git diff 忽略所有匹配 ^\s*\*.*$ 的行,因为这些都是注释(/* */的一部分)。

我找不到任何方法告诉 git diff 忽略特定行。

我已经尝试设置一个 textconv 属性,使 Git 在比较文件之前将文件传递给 sed,这样 sed 就可以去掉有问题的行——问题在于 git diff --name- status 实际上并没有区分文件,只是比较哈希值,当然所有的哈希值都发生了变化。

有办法吗?

最佳答案

这是一个适合我的解决方案。我已经在 git (log|diff) -G<regex> 上写下了解决方案和一些额外的缺失文档选项。

它基本上使用与之前答案相同的解决方案,但专门针对以 * 开头的评论或 # , 有时在 * 之前有一个空格... 但它仍然需要允许 #ifdef , #include等变化。

look ahead and look behind好像不支持-G选项,? 也没有总的来说,我在使用 * 时遇到了问题, 也。 +不过,似乎运作良好。

(注意,在 Git v2.7.0 上测试)

多行注释版

git diff -w -G'(^[^\*# /])|(^#\w)|(^\s+[^\*#/])'
  • -w忽略空格
  • -G只显示匹配以下正则表达式的差异行
  • (^[^\*# /])任何不以星号、散列或空格开头的行
  • (^#\w)任何以 # 开头的行随后是一封信
  • (^\s+[^\*#/])任何以空格开头后跟注释字符的行

基本上,SVN Hook 会立即修改每个文件的进出,并修改每个文件上的多行注释 block 。现在,我可以将我的更改与 SVN 进行比较,而无需 SVN 在评论中删除的 FYI 信息。

从技术上讲,这将允许像 #TODO 这样的 Python 和 Bash 评论显示在 diff 中,如果除法运算符在 C++ 中的新行开始,则可以忽略它:

a = b
    / c;

还有关于 -G 的文档在 Git 中似乎很缺乏,所以这里的信息应该有所帮助:

git diff -G<regex>

-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, &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-regex will not (because the number of occurrences of that string did not change).

See the pickaxe entry in gitdiffcore(7) for more information.

(注意,在 Git v2.7.0 上测试)

  • -G使用基本的正则表达式。
  • 不支持 ? , * , ! , { , }正则表达式语法。
  • () 分组和 OR-ing 组与 | 一起工作.
  • 通配符,例如 \s , \W等。
  • 支持前视和后视。
  • 开始和结束线 anchor ^$工作。
  • 此功能自 Git 1.7.4 起可用。

排除的文件 v 排除的差异

请注意 -G选项过滤将被差异化的文件。

但是如果一个文件被“diffed”,那些之前被“排除/包含”的行将所有显示在 diff 中。

例子

只显示至少有一行提到 foo 的文件差异.

git diff -G'foo'

显示除以 # 开头的行以外的所有内容的文件差异

git diff -G'^[^#]'

显示有差异的文件 FIXMETODO

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(&regex, needle, cflags);
    regexp = &regex;

// 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.

关于git - 如何让 'git diff'忽略评论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16527215/

相关文章:

diff - 使用 Aptana 比较两个文件

emacs magit 差异突出显示

image - “Diff” 使用 ImageMagick 的图像

node.js - 如何使用Github API推送代码?

git - git add 后未上演的更改

git - 为什么在检查最近的提交后我有一个分离的 HEAD?

git - 在Git中,如何列出分支A中存在但分支B中不存在的所有文件

git - 如何使用curl从Git托管站点下载git存储库中的原始文件?

visual-studio-code - vscode 是否可以显示由像 SourceTree 这样的帅哥压缩的 git diffs?

github - 为什么我的 Github 'Open pull request' 页面中有一条橙色线?