题 如何让Git忽略文件模式(chmod)的变化?


我有一个项目,我必须在其中更改文件的模式 chmod 开发时到777,但主要回购不应该改变。

Git接受了 chmod -R 777 . 并将所有文件标记为已更改。有没有办法让Git忽略对文件进行的模式更改?


1891
2017-10-16 21:43


起源


在Windows上的Ubuntu上使用Windows + Bash上的git时,这很有用 - Elazar
对于只想忽略特定调用的权限更改的任何人 git diff,因此谁不想改变他们的Git配置文件:你可以使用 git diff -G. 每 捷思锐的 回答 这里。 - sampablokuper


答案:


尝试:

git config core.fileMode false

GIT-配置(1)

core.fileMode
       If false, the executable bit differences between the index and the
       working copy are ignored; useful on broken filesystems like FAT.
       See git-update-index(1). True by default.

-c flag可用于为一次性命令设置此选项:

git -c core.fileMode=false diff

而且 --global flag将使其成为登录用户的默认行为。

git config --global core.fileMode false

警告

core.fileMode 不是最佳做法,应谨慎使用。此设置仅涵盖模式的可执行位,而不包括读/写位。在许多情况下,你认为你需要这个设置,因为你做了类似的事情 chmod -R 777,使所有文件都可执行。但在大多数项目中 出于安全原因,大多数文件不需要也不应该是可执行的

解决此类情况的正确方法是分别处理文件夹和文件权限,例如:

find . -type d -exec chmod a+rwx {} \; # Make folders traversable and read/write
find . -type f -exec chmod a+rw {} \;  # Make files read/write

如果你这样做,你将永远不需要使用 core.fileMode,除了非常罕见的环境。


3117
2017-10-16 21:53



如果你这样做 git config --global core.filemode false 你只需要为所有回购一次这样做。 - Greg
这对我来说不起作用,直到我修复了它应该是fileMode而不是filemode - tishma
@tishma:Git配置部分和变量名称是 根据文档不区分大小写,请参阅CONFIGURATION FILE部分,如果上述内容对您不起作用,则原因不同。 - Greg Hewgill
@donquixote:The git config 命令将设置写入正确的配置文件(.git/config 仅适用于当前存储库,或 ~/.gitconfig 如果用的话 --global)。 - Greg Hewgill
@ zx1986:没关系。从 git配置:“变量名称不区分大小写,......” - Greg Hewgill


工作树中的undo模式更改:

git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x
git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x

或者在mingw-git中

git diff --summary | grep  'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x
git diff --summary | grep  'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x

247
2018-01-18 02:20



在OS X Lion上,省略 -d'\n' 部分来自 xargs 因为这是非法的论点(并且不需要)。 - Pascal
您可以忽略有关“chmod:在'+ x'之后缺少操作数”的任何错误 - Casey Watson
这是最新的吗?我得到'chmod:太少的论点'在mingw - hammett
@Pascal @pimlottc -d指定分隔符为换行符而不是任何空格。 BSD xargs没有该选项,但您可以通过管道输出 tr '\n' '\0' 然后使用 -0 arg到xargs使用NUL作为分隔符。 - Mark Aufflick
很酷, tr 事情有效!这是OSX的完整命令: git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x - K.-Michael Aye


如果要为所有回购设置此选项,请使用 --global 选项。

git config --global core.filemode false

如果这不起作用,你可能正在使用更新版本的git,所以试试吧 --add 选项。

git config --add --global core.filemode false

如果你在没有--global选项的情况下运行它并且你的工作目录不是repo,你就会得到

error: could not lock config file .git/config: No such file or directory

115
2018-04-21 12:00



在git版本1.7.9.6(Apple Git-31.1)上对我不起作用 - Filip Kunc
看起来后来GIT使用 --add,如在 git config --add --global core.filemode false - mgaert
如果repo的本地配置已经有filemode = true,则更改全局配置将无济于事,因为本地配置将覆盖全局配置。将不得不改变一次机器的每个repo的本地配置 - Syed Rakib Al Hasan
请:用syedrakib的警告更新这个答案!在我找到它之前,一切都感到疯狂,之后感觉很完美。 - jerclarke


如果

git config --global core.filemode false

不适合你,手动完成:

cd into yourLovelyProject folder

cd进入.git文件夹:

cd .git

编辑配置文件:

nano config

将true更改为false

[core]
        repositoryformatversion = 0
        filemode = true

- >

[core]
        repositoryformatversion = 0
        filemode = false

保存,退出,转到上层文件夹:

cd ..

重新启动git

git init

你完成了!


66
2017-08-06 13:10



而不是编辑 .git/config, 一个简单的 git config core.fileMode false 在你的项目的根目录就足够了。如果您编辑配置文件,则最好完全删除该指令,以便拾取全局指令。 - Felix
-1如果git config --global不起作用,则表示您没有权限在系统级别执行此操作,删除 global 选项与手动编辑.git / config完全相同 - CharlesB
@CharlesB不正确 - 答案提供了一种解决方法,将选项直接放在项目中,使其成为项目特定的。这不适用于您将来制作/结帐的其他git项目,但适用于您正在处理的项目。 (让我们确保消除歧义 ~/.gitconfig,和 ~/project/.git/config) - sircapsalot
一旦这个运行了 git init 我们应该将filemode设置回true吗? - Jordan


添加到 Greg Hewgill回答 (使用 core.fileMode 配置变量):

您可以使用 --chmod=(-|+)x 的选择 git update-index (低级版本的“git add”)更改索引中的执行权限,如果使用“git commit”(而不是“git commit -a”),将从中获取执行权限。


48
2017-10-16 22:03



这应该被编辑成Greg Hewgill的答案而不是作为单独的答案添加,从而创建一个具有单一明确表示的最高答案。 - Greg
@Greg:一个人需要有足够的积分来编辑自己的答案;我想我当时没有足够的编辑权限。 - Jakub Narębski
@Jakub我认为你现在有足够的声誉:)这个命令对于一个示例文件会是什么样子? - Alex Hall


您可以全局配置它:

git config --global core.filemode false

如果上述方法不适合您,原因可能是您的本地配置会覆盖全局配置。

删除本地配置以使全局配置生效:

git config --unset core.filemode

或者,您可以将本地配置更改为正确的值:

git config core.filemode false


32
2018-01-21 09:12



如果主要答案对你没有帮助 - 试试这个。如果要检查本地配置而不进行修改,请检查 git config -l (列出当前配置 - 本地和全局) - Krzysztof Bociurko


如果你已经使用过 CHMOD 命令已检查文件的差异,它显示以前的文件模式和当前文件模式,如:

新模式:755

旧模式:644

使用以下命令设置所有文件的旧模式

sudo chmod 644 .

现在使用命令或手动将core.fileMode设置为配置文件中的false。

git config core.fileMode false

然后应用chmod命令来更改所有文件的权限,例如

sudo chmod 755 .

并再次将core.fileMode设置为true。

git config core.fileMode true

对于最佳实践,请不要始终将core.fileMode保留为false。


16
2017-10-13 07:34



你是说整个项目(开发,分期和生产)应该是755? - Daniel
@Daniel Feb:没有。只改变必要文件的模式。 - Kishor Vitekar
For best practises don't Keep core.fileMode false always 你是什​​么意思,你应该解释一下。 - bg17aw
For best practises don't Keep core.fileMode false always. 某些文件系统(例如FAT)不支持文件权限,因此操作系统将报告默认值(无论如何我的系统为766)。在这种情况下, core.filemode 在本地配置中绝对必要,除非您希望通过不必要的和无意的权限更改来破坏提交历史记录 - KevinOrr
另外,你为什么还要费心改变烫发呢?如果你设置 core.filemode=false 然后git将忽略执行位更改,无需更改本地权限。除非您已经对索引添加了权限更改,否则您将缺少所需的步骤 git add 你关掉之后 core.filemode。 - KevinOrr


如果要在递归的配置文件中将filemode设置为false(包括子模块): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'


14
2017-07-16 12:23



如果该行不在配置文件中,则无效。如果要为子模块更改它,请尝试以下操作: git submodule foreach git config core.fileMode false - courtlandj


通过定义以下别名(在〜/ .gitconfig中),您可以轻松地临时禁用fileMode per git命令:

nfm = "!f(){ git -c core.fileMode=false $@; };f"

当此别名以git命令作为前缀时,文件模式更改将不会显示将显示它们的命令。例如:

git nfm status

14
2017-07-24 15:01