从git diff排除目录


179

我想知道如何从Git差异中排除整个目录。(在这种情况下为/ spec)。我正在使用git diff命令为整个软件版本创建一个diff。但是,对规格的更改与该过程无关,只会造成麻烦。现在我知道我能做

git diff previous_release..current_release app/

这将为app目录中的所有更改创建差异,但不会为lib /目录中的所有更改创建差异。有谁知道如何完成这项任务?谢谢!

编辑:我只是想清楚一点,我知道我可以只在最后减去/ spec字符串所有目录的参数。我希望有一种方法可以在命令中真正排除单个目录。


4
我发现了这个令人惊奇的问题,因为我的目标是忽略子模块。在这种情况下,如果您像我一样幼稚,那么这个问题可能会更有帮助。
brandizzi 2012年

奇怪的是,我们在2016
Michael Z

Answers:


138

假设您使用bash,并且启用了扩展globlob(shopt -s extglob),则可以从shell端进行处理:

git diff previous_release current_release !(spec)

省去您列出所有其他事情的麻烦。

或者,与外壳无关:

git diff previous_release current_release --name-only | grep -v '^spec/' \
    | xargs git diff previous_release current_release --

您可以将其包装在一个单行的shell脚本中,以免自己不得不重新输入参数。


1
PS通配符不匹配的隐藏文件,所以如果你迷恋,你可能想粘性上.!(.|),以匹配一切开始了.,除了...
卡斯卡贝尔

这似乎不适用于全新的文件或跨分支删除的文件。我收到错误,导致脚本无法执行,无法对付它。
Graham Christensen

2
@Graham:我相信--刚才添加的应该可以解决该问题。
卡斯卡贝尔2011年

1
很棒的答案。我只想显示名称(而不是实际的差异),所以我也必须--name-only在最后添加。
2014年8

1
玩完它之后,只想添加一下,如果您更改文件名,它将抛出一个错误,但是您所要做的就是添加-- path/of/new/file,它将解决这个问题:)
2014年

318

根据此答案,您还可以使用:

git diff previous_release..current_release -- . ':!spec'

这是一个新的git功能,可以排除某些路径。它应该比各种shell oneliners更可靠。

我将其发布在这里,因为这个问题仍然是“ git diff exclude path”的第一名。


4
喜欢这个答案。如果添加选项,则在双破折号之前这样做。例如: git diff previous_release current_release --name-status -- . ':!spec'
liamvictor

不知道我可以使用分支名称为current_releaseprevious_release-使我微笑,当我想通了。
trueheart78 '16

2
什么对我有用git diff --stat dev -- . ':!/Mopy/Docs/*'。什么都没有对我的工作git diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')'和变化
Mr_and_Mrs_D

真的很有帮助。这是语法,查看是否更改了除database.yml以外的任何文件:git diff --check -- . ':!config/database.yml'
Dan Kohn

17
也可以像这样排除多个项目:git diff previous_release current_release -- . ':!file_a' ':!file_b'
PseudoNoise

36

如果要指定多个路径以排除git diff,则只需在末尾添加其他排除参数,例如从统计信息中排除vendorbin目录中的所有内容:-

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'

33

您可以尝试为lib目录中的所有文件取消设置diff属性。
.gitattributes

lib/* -diff

racl101添加了评论

补充一下,对于那些想要限制git diff特定类型的文件在特定目录及其子目录内输出的用户,例如Webpack捆绑.js文件所生成的所有JavaScript ,例如,您可以添加至.gitattributes

dist/js/**/*.js -diff

然后,您在git diff输出中看不到所有杂音,而是显示为:Binary files ... differ这样做更有用。


但这会删除我所有差异的规格。我仍然希望正常情况下在spec文件夹中看到我的差异,只是当我运行此“发布”差异时不显示
Mysrt 2010年

2
@Mystr:您可以将.gitattributes文件设置在仅用于这种“发布”差异的特殊分支中;)在该特殊分支的基础上重新建立基础,current_release然后从此处进行差异。
VonC 2010年

对于跨分支删除的文件,这似乎也不起作用。删除的文件仍然显示完整的差异。
Graham Christensen

对我不起作用。_路径是否特殊?_site/* -diff
Marius

@MariusAndreiana不,“ _”并不特殊。您可以通过以下命令检查哪个gitattributes规则适用于该文件夹的文件:git-scm.com/docs/git-check-attr
VonC

22

Git diff现在接受自定义排除格式: git diff -- ':(exclude)lib/*'

如果您有很多重复的文件夹名称('/ app','/ lib'等),请小心,因为这将排除相对于当前工作目录和git根目录的文件。


1
您是否遗漏了一个点,不是git diff -- . ':(exclude)lib/*'吗?
Nicolas Dermine's

1
@NicolasDermine不,尽管您写的内容是等效的。路径的“包含”部分也是可选的。这就是为什么您只需要git diff处理与当前路径相关的所有事情,而不是要求git diff -- .
MaxPRafferty

注意:在Windows计算机上,请使用双引号,例如git diff -- ":(exclude)lib/*"
cnlevy

不知道为什么,但是对我来说,它只适用于点,如@NicolasDermine所建议。我在win10上使用Cmder。
Olivvv

3

相对于git根目录

git diff 接受可选的排除

git diff -- ":(exclude)thingToExclude"

您可能要添加一些通配符

git diff -- ":(exclude)*/thingToExclude/*"

定位特定文件类型

git diff -- ":(exclude)*/$1/*.png"

使用一些语法糖

git diff -- ":!/\$1/"

或为您的dotfile删除一个小脚本

.bash_profile.zshrc

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.