Git在更新文件时更改默认umask

Git在更新文件时更改默认umask,git,permissions,umask,Git,Permissions,Umask,我对Git有问题。我在Google和StackOverflow中搜索了一个解决方案,但没有任何帮助 问题是每次git更新工作目录中的某个文件时(当我签出分支或合并分支时,等等),文件权限都会更改,从而添加“可写入组”标志。 如果文件可写入组,我的apache会显示文件的“Error 500” 例如: 我有一个index.php文件。权限为“-rwxr-xr-x”。当前(活动)分支是主分支。此文件已在“开发”分支中更改。 我执行“git checkout develope”,文件index.php

我对Git有问题。我在Google和StackOverflow中搜索了一个解决方案,但没有任何帮助

问题是每次git更新工作目录中的某个文件时(当我签出分支或合并分支时,等等),文件权限都会更改,从而添加“可写入组”标志。 如果文件可写入组,我的apache会显示文件的“Error 500”

例如: 我有一个index.php文件。权限为“-rwxr-xr-x”。当前(活动)分支是主分支。此文件已在“开发”分支中更改。 我执行“git checkout develope”,文件index.php获得权限“-rwxr-x”(添加了可写入组)。我的网站停止工作了。因为apache不允许在php文件中使用此标志(我不知道为什么,但我无法更改此标志)

每次执行“git checkout develop”时,我还需要执行“chmod g-w index.php”。我不喜欢执行两个命令(有时我忘记执行这两个命令,我的站点无法工作)

我能做些什么来解决这个问题? 我认为这与乌马斯克有关。我做了一些我在网上发现的小把戏,但没有任何效果


谢谢。

快速回答是将此shell函数放入您的
~/.profile
中。解释如下

git(){(umask 0022; command git "$@")}
A是进程的属性。它是从父进程继承的,以后可以从内部进行更改。更改umask的命令通常也被命名为umask

Git没有用于设置其umask的配置选项,它在执行后不会更改其umask。您必须从外部设置Git的umask,让它从父进程(通常是shell)继承

嗯,你似乎不喜欢除了git之外的任何东西都改变了umask。因此,让我们在执行
git
时更改它

当shell执行一行时,它会获取该行的第一个字,并尝试查找该名称的函数。只有在没有命令的情况下,它才会尝试在
PATH
中找到该名称的命令。我上面写的函数名为
git
,因此,现在直接调用
git
将执行它,而不是执行
git
命令

该函数执行子shell,更改其umask,并从子shell内部执行
git
命令。Git完成工作后,子shell也会退出,并且原始shell实例仍将具有原始umask


但是,该函数还显示如何绕过自身。如果通过
命令git
或甚至
/usr/bin/git
调用
git
,则不会调用该函数。不过,对于任何体面的使用来说,这已经足够了。

在签出后使用钩子更改文件模式可以在问题出现后修复问题。执行钩子时,文件系统中已经存在错误的文件模式。如果一个请求刚好在签出和钩子执行之间到达,服务器将响应500错误。但无论如何,您可能对这个解决方案感兴趣

您需要在所有必要的文件上运行
chmod g-w
钩子。钩子是
.git/hooks/post checkout
,应该是可执行的,并获取当前的
头作为第二个参数($2在shell中)。钩子可以是这样的:

#!/bin/bash
git ls-files -z --with-tree="$2" | xargs -0 chmod g-w --

由于钩子没有检出文件列表,这可能是最好的实现。它会更改当前
头中所有文件的模式

允许文件作为二进制文件执行有点危险。 无论如何,我解决了乌玛斯克的问题。我的
post receive
脚本如下所示:

!/bin/sh
umask 002
GIT_WORK_TREE=/var/www/site git checkout -f
因此,
文件权限
设置为
664
目录权限
设置为
775
,这非常适合我


另外,在
git
用户的
.profile
文件中设置umask没有任何效果,我不明白为什么,如果你知道为什么会发生这种情况,请评论一下。

我刚刚在Ubuntu 14.04(Trusty)上签出通过NFS挂载的主目录的repo时遇到了这个问题使用后端口的Xenial版本4.x linux内核。 Git克隆到本地目录是正常的。更奇怪的是:第二台Ubuntu14.04服务器在同一个挂载目录上没有出现同样的问题

经过多次探索,我发现git使用strace调用open()系统调用来创建每个文件,选项为O_create、O_WRONLY和O_EXCL,模式为0666,但接下来的syscal是针对该文件的fstat(),并告诉我它是模式0700。就我而言,这个问题只影响到回购协议中的某些文件。尽管“git ls index”显示大多数文件的模式为0644,但其中一些文件的创建是正确的,而另一些文件的创建是错误的;虽然总是相同的文件在克隆上有错误的权限

我注意到两个系统的内核版本不同,然后发现了以下错误:

将内核升级到4.4.0-98(从4.4.0-59)为我解决了这个问题。
我检查了一些仍然使用3.x版Linux内核的主机,这些主机没有问题。

有什么原因不能正确设置umask(即设置为0022或类似版本)?如何做到这一点?要设置umask吗?这是系统变更还是仅git变更?如果系统无法更改,请运行
umask 0022
。要为交互式会话设置它,请将此命令放入
.bashrc
或shell的等效程序中。要始终设置它,请在您的
.profile
中设置它。我不想更改任何系统设置。该站点与此用户一起运行。我担心这会影响其他事情。有没有办法只通过更改git设置来解决这个问题?我知道git中有更新后挂钩。但我找不到如何使用钩子解决这个问题;如果站点以该用户的身份运行,并且仅当该用户创建了不可组写的文件时才起作用,那么您肯定要将该用户的umask更改为00