如何使Git忽略文件模式(chmod)更改?


2308

我有一个项目,开发时必须将文件模式更改chmod为777,但不应在主存储库中更改。

Git启动chmod -R 777 .并标记所有文件为已更改。有没有办法让Git忽略对文件所做的模式更改?


17
在Windows上的git + Windows上的Ubuntu上使用Bash时,这很有用
Elazar 2017年

4
对于只想忽略特定调用的权限更改git diff而又不想更改其Git配置文件的任何人:您可以在此处使用git diff -G.每个Zed的答案。
sampablokuper

Answers:


3818

尝试:

git config core.fileMode false

git-config(1)

core.fileMode
    Tells Git if the executable bit of files in the working tree
    is to be honored.

    Some filesystems lose the executable bit when a file that is
    marked as executable is checked out, or checks out a
    non-executable file with executable bit on. git-clone(1)
    or git-init(1) probe the filesystem to see if it handles the 
    executable bit correctly and this variable is automatically
    set as necessary.

    A repository, however, may be on a filesystem that handles
    the filemode correctly, and this variable is set to true when
    created, but later may be made accessible from another
    environment that loses the filemode (e.g. exporting ext4
    via CIFS mount, visiting a Cygwin created repository with Git
    for Windows or Eclipse). In such a case it may be necessary
    to set this variable to false. See git-update-index(1).

    The default is true (when core.filemode is not specified
    in the config file).

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

git -c core.fileMode=false diff

并且该--global标志将使其成为已登录用户的默认行为。

git config --global core.fileMode false

全局设置的更改将不会应用于现有存储库。此外,git clonegit init明确设置core.fileMode,以true在回购的配置在讨论Git的全球core.fileMode假的克隆覆盖的地方

警告

core.fileMode这不是最佳做法,应谨慎使用。此设置仅覆盖mode的可执行位,而不覆盖读/写位。在许多情况下,您认为您需要此设置,因为您做了类似的操作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,除非在非常罕见的环境中,您将永远不需要使用。


203
如果您这样做git config --global core.filemode false,则只需对所有存储库执行一次此操作。
格雷格2012年

13
在我解决了它应该是fileMode而不是filemode的情况下,这对我不起作用
tishma

8
@tishma:根据文档, Git配置部分和变量名称不区分大小写,请参阅CONFIGURATION FILE部分,因此,如果以上内容对您不起作用,则是出于不同的原因。
格雷格·希吉尔

11
@donquixote:该git config命令将设置写入正确的配置文件(.git/config仅适用于当前存储库,或者~/.gitconfig用于--global)。
Greg Hewgill 2013年

8
@ zx1986:没关系。从git config中:“变量名不区分大小写,...”
Greg Hewgill 2015年

277

撤消工作树中的模式更改:

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

42
在OS X Lion上,请省略其中的-d'\n'一部分,xargs因为这是非法的论点(并且不需要)。
Pascal

9
您可以忽略有关“ chmod:'+ x'之后缺少操作数”的任何错误
Casey Watson

5
这是最新的吗?我在
Mingw中

7
@Pascal @pimlottc -d将分隔符指定为换行符,而不是任何空格。BSD xargs没有该选项,但是您可以通过管道传递输出tr '\n' '\0',然后使用-0arg到xargs以将NUL用作分隔符。
Mark Aufflick 2013年

10
tr太好了,事情成功了!这是OSX的完整命令:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye

135

如果要为所有存储库设置此选项,请使用该--global选项。

git config --global core.filemode false

如果这不起作用,则可能是您使用的是git的较新版本,请尝试使用该--add选项。

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

如果您在不使用--global选项的情况下运行它,而您的工作目录不是存储库,则会得到

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

5
看起来像后来的GIT使用--add,如git config --add --global core.filemode false
mgaert 2013年

14
如果仓库的本地配置已经具有filemode = true,则更改全局配置将无济于事,因为本地配置将覆盖全局配置。将不得不一次更改机器的每个存储库的本地配置
Rakib

3
请:用syedrakib的警告更新此答案!在我发现之前,一切都变得疯狂,在此之后变得很有意义。
jerclarke '16

88

如果

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

大功告成!


11
无需编辑.git/config,只需git config core.fileMode false在项目根目录中创建一个即可。如果您编辑配置文件,则最好完全删除该指令,以便选择全局指令。
菲利克斯(Felix)2014年

6
-1如果git config --global不起作用,则意味着您没有在系统级别执行此操作的权限,删除global选项的作用与手动编辑.git / config
完全相同

@CharlesB错误-答案提供了一种解决方法,方法是将选项直接放在项目中,使其特定于项目。此功能不适用于您将来制作/签出的其他git项目,但确实适用于您正在处理的项目。(确保我们消除歧义~/.gitconfig,以及~/project/.git/config
ddavison

一旦运行git init,我们是否应该将filemode设置为true?
乔丹

53

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

您可以使用--chmod=(-|+)x的选项的git更新指数(的“混帐添加”低级别的版本)来更改索引执行权限,在那里,如果你用“git的承诺”将它拾起(而不是“git的承诺-a ”)。


2
应该将其编辑为格雷格·休吉尔(Greg Hewgill)的答案,而不是将其添加为单独的答案,从而以单个明确的表示形式创建一个最高答案。
格雷格(Greg)

6
@Greg:一个人需要有足够的分数来编辑自己的答案;我认为当时我没有足够的编辑权限。
JakubNarębski2012年

1
@Jakub我认为您现在已经有足够的声誉了:)对于一个示例文件,此命令将是什么样?
亚历克斯·霍尔

38

您可以全局配置它:

git config --global core.filemode false

如果上述方法对您不起作用,则可能是您的本地配置覆盖了全局配置。

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

git config --unset core.filemode

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

git config core.filemode false


4
如果主要答案对您没有帮助-请尝试以下一种方法。如果要检查本地配置而不进行修改,请检查git config -l(列出当前配置-本地和全局)
Krzysztof Bociurko 2015年

23

如果您已经使用了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。


您是说整个项目(开发,阶段和生产)应该为755吗?
丹尼尔(Daniel)

@Daniel Feb:否。仅更改必要文件的模式。
Kishor Vitekar '16

For best practises don't Keep core.fileMode false always你是什​​么意思,你应该解释一下。
bg17aw

For best practises don't Keep core.fileMode false always.某些文件系统(例如FAT)不支持文件权限,因此OS将报告默认值(无论如何在我的系统上为766)。在这种情况下,core.filemode在本地配置中绝对必要,除非您想通过不必要的和无意的权限更改来
破坏

另外,为什么还要麻烦重新更改烫发?如果设置,core.filemode=false则git将忽略执行位更改,无需更改本地权限。除非您已经为索引添加了权限更改,否则在这种情况下您将丢失在git add关闭后需要执行的步骤core.filemode
KevinOrr '16

18

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

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

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

git nfm status

14

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


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

4

简单的解决方案:

打这个简单的命令在项目文件夹(它不会删除你原来的变化) ......它只会移除变更已被做了,而你更改项目文件夹的权限

命令如下:

git config core.fileMode错误

为什么要修改所有不必要的文件: 因为您已经用sudo chmod -R 777更改了项目文件夹权限,所以您需要修改。

您什么时候会检查更改而不做?您在使用git diff filename时发现如下

old mode 100644
new mode 100755

1

这对我有用:

find . -type f -exec chmod a-x {} \;

或反向,具体取决于您的操作系统

find . -type f -exec chmod a+x {} \;

1
这将更改文件的权限,但不会使git忽略文件的文件权限。
domdambrogia

好吧,你是对的,那不能解决git忽略的事情。
马丁·沃莱克
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.