按更改类型过滤git diff

160

有没有一种方法可以将 git diff 限制在更改的文件上?

我想看到两个提交之间的差异,但排除在其中一个中不存在的路径(添加/删除)。以下 Perl 一行说明了我想要的大部分内容:

git diff master.. | perl -lnwe 'print unless /^(new|deleted) file/../^diff/ and not /^diff/'

但这会留下 diff --git a/path b/path 行,这些行是针对新建或删除的文件。而且如果我必须解析的话(还有一个问题是,如果任何 hunk 包含与 /^diff/ 匹配的内容,则解析将失败),这样做就不太好了。

另一个我尝试过的选择是:

git diff --name-status (args) | perl -lnwe 'print if s/^M\s+//' | xargs git diff (args) --

输出效果更好了,但仍然感觉像是hackish。

5个回答

293
您正在寻找--diff-filter=M以仅显示在两个分支之间M修改的文件。
来自man git-diff

--diff-filter=[ACDMRTUXB*]

仅选择以下类型的文件:

  • A 添加的
  • C 复制的
  • D 删除的
  • M 修改的
  • R 重命名的
  • T 类型(模式)已更改
  • U 未合并的
  • X 未知的
  • B 配对已中断的
  • * 全部或无

可以使用任何过滤字符的组合。

当将*(全部或无)添加到组合中时,如果有任何与其他比较标准匹配的文件,则选择所有路径; 如果没有符合其他标准的文件,则不会选择任何内容。

此外,这些大写字母可以小写以排除。例如,--diff-filter=ad排除了添加和删除的路径。


2
在使用--diff-filter=AMR来省略已删除文件时,请避免我的一个愚蠢错误:如果您要删除文件“x”,那么git diff HEAD HEAD1 --name-only --diff-filter=AMR仍将列出“x”。为什么?因为从HEAD到HEAD1,该文件是添加的,而不是删除的。 - Christoph Grimmer
2
T的描述令人困惑。来自man git diff,“类型发生更改(即常规文件、符号链接、子模块等)(T)”。 - grimsock
如果你想使用 R(重命名文件),你需要使用 -M,它被扩展为 --find-renames - ccjjmartin
这些不同类型的文档在哪里可以找到?基本上,A、D、M、T和R都很直观,但我想知道C、U、X和B代表什么。 - DanCat
5
Nice和另一个回答指出小写字母表示排除。非常方便用于排除已删除的文件。 - Philippe Rathé

31
作为 Git 2.10(2016 年第三季度)的提醒,有一种更简单的方法可以“显示除添加/删除文件以外的所有内容”(实际上自 Git 1.8.5,即 2013 年 7 月起就已经存在)。
 git diff --diff-filter=ad master..

请看提交16726cf(2016年7月14日)由Junio C Hamano (gitster)提交。
(于2016年8月8日由Junio C Hamano -- gitster --合并到提交2f8c654中)

diff:文档化diff-filter排除

在v1.8.5时期,7f2ea5f (diff: allow lowercase letter to specify what change class to exclude, 2013-07-17)教授了"--diff-filter"机制以接受小写字母作为排除的内容,但我们忘记记录它。
因此,diff-options的文档现在(终于)包括:
这些大写字母可以变为小写字母以进行排除。
例如:--diff-filter=ad排除已添加和已删除的路径。
请确保使用Git 2.36 (Q2 2022)

6
要查看所有修改过和新增的文件,你可以使用:

git diff --name-only --diff-filter=ACMR PREV_VERSION master

PREV_VERSION 是您第一次提交的哈希值。

要获取 zip 格式的导出文件,您可以使用以下代码:

git archive --output=export.zip HEAD $(git diff --name-only --diff-filter=ACMR PREV_VERSION HEAD)

注意: .gitignore 文件不在export.zip中。

5
你可以使用 --diff-filter 标志来精确地执行此操作。git diff --diff-filter=CMRTUXB master.. 应该显示除添加/删除文件外的所有内容。

0

我使用了Notepad++(Windows)和正则表达式来从diff文件中过滤掉扩展类型和特定路径。

^Index.*\.(dll|pdb|exe|txt|zip|log|ism|resx|tlog|htm|lib)$[\s\S.]*?^Index
^Index: Shared/.+$[\s\S.]*?^Index
^Index: Next/source/Utility/.+$[\s\S.]*?^Index

唯一的问题是,当它到达结尾时。您必须使用“ctrl + home”再次开始,直到找不到为止。

(用“Index”替换找到的内容)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接