我遇到Git问题。我在Google和StackOverflow中搜索了一个解决方案,但没有任何帮助。
问题是,每当git更新工作目录中的某个文件时(当我签出分支或合并分支时等),则更改文件权限,以便添加“可写入组”标志。 如果该文件可写入组,我的apache会显示“错误500”。
实施例: 我有一个文件index.php。权限是“-rwxr-xr-x”。当前(活动)分支是主分支。此文件在分支“develop”中已更改。 我执行“git checkout develop”并且文件index.php获得权限“-rwxrwxr-x”(可写入组添加)。我的网站停止工作。由于apache不允许在php文件中使用此标志(我不知道为什么但我无法更改此内容)。
每次执行“git checkout develop”时,我都需要执行“chmod g-w index.php”。我不喜欢执行两个命令(有时我忘记执行此操作而我的网站无效)。
我该怎么做才能解决这个问题? 我认为这与umask有关。我在网上找到了一些技巧,但没有任何效果。
感谢。
答案 0 :(得分:9)
允许将文件作为二进制文件执行是危险的。
无论如何,我用umask解决了这个问题。我的post-receive
脚本如下:
!/bin/sh
umask 002
GIT_WORK_TREE=/var/www/site git checkout -f
因此,file permission
设置为664
,directory permissions
设置为775
,这完全适合我。
P.S。在.profile
git
用户的{{1}}文件中设置umask无效,我不明白为什么,如果你知道为什么会这样,请注释掉。
答案 1 :(得分:8)
快速回答是这个shell函数放在你的~/.profile
中。解释如下。
git(){(umask 0022; command git "$@")}
umask是流程的属性。它继承自父进程,可以在以后从内部进行更改。更改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
或command git
致电/usr/bin/git
,则系统不会调用此功能。但是,对于任何体面的使用来说,这已经足够了。
答案 2 :(得分:4)
我在Ubuntu 14.04(Trusty)上使用backported Xenial版本4.x linux内核检查通过NFS挂载的主目录的回购时遇到了这个问题。 Git克隆到本地目录很好。更奇怪的是:第二台Ubuntu 14.04服务器在同一个安装目录中没有出现同样的问题。
经过大量的讨论之后我能够看到使用strace git调用open()系统调用来创建每个文件,其中包含选项O_CREAT,O_WRONLY和O_EXCL以及模式0666,但是接下来的syscal是一个fstat ()对文件,并告诉我这是模式0700。在我的情况下,问题只影响仓库中的某些文件。尽管'git ls-index'显示大多数文件的模式0644,但其中一些正确创建而其他文件没有;虽然它总是与克隆的权限错误相同的文件。
我注意到两个系统之间的内核版本存在差异,然后发现了以下错误:https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1654288
将内核升级到4.4.0-98(从4.4.0-59开始)为我解决了这个问题。 我检查了一些仍然使用版本3.x Linux内核的主机,这些没有问题。
答案 3 :(得分:1)
结帐后使用挂钩更改文件模式是在问题已经出现后修复问题。执行挂钩时,文件系统中已经存在错误的文件模式。如果请求在结账和挂钩执行之间到达,服务器将响应500错误。但无论如何,您可能对此解决方案感兴趣。
您需要在所有必需文件上运行post-checkout
挂钩chmod g-w
。钩子是.git/hooks/post-checkout
,应该是可执行的,并将当前HEAD
作为第二个参数(shell中为$ 2)。钩子看起来像这样:
#!/bin/bash
git ls-files -z --with-tree="$2" | xargs -0 chmod g-w --
由于钩子没有检出文件列表,这可能是最好的实现。它会更改当前HEAD
中所有文件的模式。