如何根据文件扩展名过滤git diff?

242

是否有选项可以限制git diff仅针对给定的文件扩展名进行比较?

10个回答

334

是的,如果你确保git展开通配符而不是你的shell,则它将在任何级别匹配,因此像这样(引号很重要)应该完全可以工作。

git diff -- '*.c' '*.h'

1
好的,我的git版本太旧了。使用1.7.8版本就像广告中描述的那样工作得很好。非常棒。 - Mat
8
我的方法使用大括号扩展,就像 git diff -- *.{c,h,etc} 这样的用法。 - Matt Fletcher
9
双破折号非常重要,例如:git diff master HEAD -- "*filename.txt"。同时,git diff master HEAD --name-only也是非常有用的。 - neaumusic
3
还必须在 Git 仓库的根目录执行此操作。 - John Jiang
1
可能是一个有趣的提示:在Windows上使用需要双引号。 - lcnittl
显示剩余3条评论

38

这是我使用的方法,可以递归地包含文件(包括当前目录):

git diff -- '***.py'

3
对我来说,这是最好的解决方案。您还可以排除一些文件/目录。例如:git diff -- '***.py' ':!.Trashes' - Bartosz
三个星号(与一个星号相比)有什么作用? - Jann Poppinga
如果我没记错的话,双星号可能表示嵌套目录(甚至是空目录),而单星号和 .py 表示文件名。因此,在当前目录或任何嵌套目录中应该有一个 *.py 文件。 - Bohumir Zamecnik
“*.py” 还包括嵌套目录中的 py 文件(在 git 版本 2.28 上测试通过) - Blaise

10

你可以使用shell的globstar(它执行递归搜索)1,2:

shopt -s globstar 
git diff -- *.py **/*.py

或使用find:

find -name '*.py' -print0 | xargs -0 git diff --

这两个都是特殊名称和空格的证明。尽管您可能希望筛选具有.py扩展名的目录 :)


1 通常我喜欢执行git diff -- {.,**}/*.py

2 当启用globstar时,git diff -- **/*.py已经包括./*.py。在Bash的手册页中:'如果跟在 / 后面,则两个相邻的 * 只会匹配文件夹和子文件夹。'


如果存储库中没有Python文件,则“find”版本无法工作。因此,如果您有全局钩子,您将开始比较非Python文件 :( - Matthieu Brucher

6

在测试git版本2.18.0时,文件扩展名应该用双引号引起来。如果您想查找本地存储库和远程存储库之间的最后差异,在拉取后,您可以使用以下命令:

git diff YourBranchName@{1} YourBranchName --name-only "*.YourFileExtionsion"

例如:

git diff master@{1} origin/master --name-only "*.cs"

1
当我在扩展名前提供--时,它对我起作用,就像这样: git diff master@{1} origin/master --name-only -- "*.cs" - 333

4

对于简单的文件模式,这似乎是有效的:

$ git ls-files -zm '*.txt' | xargs --null git diff

可以安全地处理空格,并且您也可以拥有多个扩展:

$ git ls-files -zm '*.h|*.c|*.cpp' | xargs --null git diff

3

扩展程序的命令行参数。

git diff *.py

作为替代方案,您可以将find管道传递给git diff:
find . -name '*.py' -type f | git diff --

你可以使用git diff *.py,无需响亮的标题。 - sehe
1
“shout headings”是一个shell脚本中的#-注释。 - hughdbrown
这是唯一对我有效的解决方案,引号(等等)在Windows命令提示符上无法正常工作。 - Ed Bayiates
最新的git版本已经破坏/删除了这个功能。根据@marjan.javid在下面的回答,现在需要双引号。没有任何警告,git-diff就停止工作了:(。花了一段时间才弄清楚发生了什么变化(以及为什么git-diff现在对于以前总是有效的相同输入返回零结果)。 - Adam

1

注意参数顺序会产生影响...例如:

git diff master --name-only --relative -- "**/*.ts" "**/*.tsx" "**/*.js" "**/*.jsx" "**/*.vue"

“diff”需要跟随“master”。

使用 **/*.ext 无法匹配 foo.ext(不在文件夹中)。因此应该使用 ***.ext 等。 - Matthew D. Scholefield

1

以上的答案似乎都不适用于我在Windows上使用git bash。我不确定这是版本问题(我使用的是1.8.4)还是Windows/bash问题;此外,在我的情况下,我想要比较两个分支,每个分支都有另一个分支中不存在的附加文件(因此基于“find”的方法不足)。

无论如何,这对我起作用了(在我的示例中,查找Python文件之间的差异):

git diff branch1 branch2 -- `git diff --summary branch1 branch2 | egrep '\.py$' | cut -d ' ' -f 5`

这个 https://dev59.com/r2oy5IYBdhLWcg3wcNhO#8554987 是有效的,但是在Windows中必须使用双引号而不是单引号。 - lcnittl

0

git diff 只会显示未暂存文件的差异。

我发现这个问题是因为我想从 git diff 中排除 .info 文件。我通过使用 git add *.info 将其暂存,从而减少了剩余的文件。


0
我得到了这个:
commit=<the_commit_hash_goes_here> && git diff --name-only $commit | grep -i Test | egrep -v '\.sql$' | xargs git diff $commit --

仅当文件名包含单词“test”(不区分大小写)且不以 .sql 结尾时,此处显示指定提交的差异,根据您的情况修改管道。


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