我能否让git diff忽略权限更改?

91

我无意中更改了整个目录树的权限并将该更改与其他内容更改一起提交。

我使用类似如下的命令:

tar -czf deploy.tar git diff --name-only v1 v2

来生成一个包含两个标签之间修改的文件的 tar 文件,问题是现在由于权限更改,几乎所有目录树都被列为已修改。

有没有办法告诉 git diff 忽略那些只更改了权限的文件?


3
这可能是如何让git忽略文件权限变化(chmod)?的重复问题。 - Leonel
3个回答

177
这将告诉Git忽略权限:
git config core.filemode false

4
也许这可以防止将权限更改的文件添加到提交中,但在我的情况下,这些文件已经被提交、推送和打了标签,你提出的命令对我没有帮助。我想我需要编写一种Bash脚本来解析git diff的输出,以删除有关模式更改的行,并将结果传递给tar。如果您有任何想法,请务必告诉我。 - Cesar
3
@Cesar:哦!所以你已经提交了更改的权限?抱歉,我漏掉了那部分内容。如果你还没有将更改推送到另一个存储库或合并到另一个分支,我建议修正/重新设置提交来解决它。 - Daniel Stutzbach
15
git diff -G.(参见https://dev59.com/4GEh5IYBdhLWcg3wdjPt) - Fabian Schmengler
为了使此设置全局化,您可以使用 --global 选项:$ git config --global core.filemode false - dxvargas
4
gif diff -G.结尾的点(.很重要 - rodrigobb
显示剩余2条评论

33

使用-G<regex>选项("查找差异的补丁文本包含与<regex>匹配的添加/删除行。")搜索任何更改 - 即 .。仅包含权限更改的更改不会匹配此条件,因此它们将被忽略。

所以:git diff -G.


由于某种原因,此解决方案与 --ignore-space-at-eol 不兼容。如果我执行 git diff -G. revA..revB,则可以抑制模式更改的报告,正如所需的那样,但我确实看到了行尾更改。如果我添加 --ignore-space-at-eol,则可以抑制行尾更改,正如所需的那样,但是模式更改会重新出现。为什么会这样?在我看来,它们似乎并不根本相关。我想抑制两者。 - jez
如果你使用-G选项,那么对于二进制文件的更改不会在差异中显示。 - Malcolm Boekhoff
发现如果你加上“--text”,这个技巧就能奏效。 - Malcolm Boekhoff

15

我在故意删除源代码文件(约26K个文件)的执行权限后遇到了这个问题。然后,git diff显示所有文件都已更改!使用core.filemode的答案对我没有帮助,因为它只影响与工作目录的差异,而不是与库中2个提交的差异。

解决方法是使用(非常可怕的)filter-branch命令。特别是,你只需要输入以下内容:

git filter-branch -f --tree-filter 'find * -type f | xargs chmod 644' -- --all

从您的工作目录根目录开始。当然,在进行操作之前,请确保首先复制您的存储库,即

cp -pr ~/repo.git ~/repo-orig.git

如果需要重新尝试,可以使用类似的方法。

享受!


1
有趣 (+1)。我已将其包含在我的答案中,网址为https://dev59.com/rGnWa4cB1Zd3GeqP4dFO#12979453(因为您自己的答案已被删除) - VonC

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