使用git签出文件时如何找出导致文件权限更改的原因?

Posted

技术标签:

【中文标题】使用git签出文件时如何找出导致文件权限更改的原因?【英文标题】:How to find out what causes file permissions to change when checking out files with git? 【发布时间】:2016-12-11 20:53:59 【问题描述】:

将文件推送到我们的服务器后,执行以下 post-receive 钩子:

#!/bin/sh
export GIT_WORK_TREE=/home/user/www/
git checkout -f

但是,文件在结帐时获得了一个非常奇怪的600 权限,而文件夹700。这不是我所期望的(在我们的其他服务器上,我们得到644755)。从this thread我了解到git没有设置权限,所以不怪git。我的问题是:什么是?我怎样才能弄清楚这个问题的原因是什么?

我已经通过在结帐时运行额外的脚本来修复权限暂时解决了这个问题,但我有兴趣解决根本原因。

我正在使用 gitolite 来管理存储库,但我怀疑这就是原因。但同样,我很高兴知道我可以从哪里开始,因为在这一点上我不确定如何调查这个问题。

根据最初的答案,我查看了服务器上的 umask 设置。 git 用户(即用于上传文件的用户),umask 设置为 0002。这在以下练习中得到确认:

git@server:~$ umask
0002
git@server:~$ touch newfile
git@server:~$ ls -la newfile
-rw-rw-r-- 1 git git 0 Aug  5 10:46 newfile

其他细节:

Linux 用于服务器端和开发端 在本地 repo 中,权限为 755 和 644 filemode 在 .git/config 中设置为 true

【问题讨论】:

读出来:***.com/questions/2517339/… 感谢@CodeWizard。但是 git 应该只跟踪可执行位,所以它不可能是 git 导致读/写权限丢失,对吧? 【参考方案1】:

和“Git change default umask when update file”一样,你能把 umask 添加到你的钩子里吗?

#!/bin/sh
umask 002
export GIT_WORK_TREE=/home/user/www/
git checkout -f

这应该将文件权限设置为 664,将目录权限设置为 775。


关于gitolite,check the umask section of the gitolite.rc file:

$UMASK,八进制,默认 0077

gitolite 使用的默认 UMASK 为所有 repos 及其内容提供 rwx------ 权限。 想要运行 gitweb(或 cgit、redmine 等)的人意识到这是行不通的。

处理这个问题的正确方法是给这个变量一个类似0027的值(注意语法:前导0是必需的),然后让用户运行网络服务器(apache、www-data等) 'git' 组的成员。

如果您已经安装了 gitolite,则必须手动修复现有文件(对于 umask0027,将是 chmod -R g+rX)。这是因为umask 只影响新创建文件的权限,而不影响现有文件的权限。

【讨论】:

感谢@VonC,但这只是解决症状而不是问题,对吧?我已经添加了一些额外的接收后代码来修复权限,但我的问题是:如何找出导致权限更改的程序/设置?毕竟上传600的文件是不正常的吧? @user32421 这不是对症状的修复,而是实际的解决方案。这与运行该挂钩的 linux 配置文件相关联:cyberciti.biz/tips/…。通过在挂钩中添加 umask,您不再依赖该配置文件设置。 @user32421 这是 Linux 相关的(其中用户文件创建模式掩码 (umask) 用于确定新创建文件的文件权限),与 git 无关。 感谢@VonC,但如果问题与 umask 设置有关,那么我宁愿在配置文件设置中更改它,而不是针对每个存储库。但正如更新后的帖子中提到的,问题似乎不在于 umask 设置。 @user32421 在配置文件中更改它意味着您依赖于执行环境。将它设置在钩子中意味着钩子将做正确的事情,独立于配置文件。【参考方案2】:

但是,文件在结账时获得了非常奇怪的 600 权限,而文件夹获得了 700 权限。

您的 shell 似乎有一个限制性的 umask 设置,可能是umask 0177

从这个帖子我了解到 git 没有设置权限,所以 git 不是罪魁祸首。

不,这是你的 shell 的 umask 设置。

我的问题是:[...] [如何] 找出这个问题的原因是什么?

运行umask,它会告诉你当前的设置是什么。就像是0177 或类似的。 如果你想知道为什么, 你需要查看/bin/sh使用的rc文件, 很可能是.profile.bashrc,以及其他来源的文件。

您可以有非常严格的umask 设置,但在脚本中覆盖它们,方法是按照@VonC 的建议添加umask 行。

【讨论】:

谢谢,确实是这样,但我检查了这个并且 git 用户有 umask '0002',所以这仍然不能解释它。我尝试以 git 用户身份运行“touch newfile”,它获得了正常权限。将更新我的答案以添加这些见解。还有其他想法吗? 将这些命令放入你的 post-receive 钩子中,例如umask > /tmp/debug.log 并测试它,并查看/tmp/debug.log 的内容以及该文件的权限。交互式 shell 中的 umask 设置很可能与 post-receive 挂钩中的有效设置不同 谢谢,这个练习确实表明我的交互式 shell 的 umask 确实不同于登录用户的 umask。我不知道为什么会这样。让我对此提出一个新问题,以免在 cmets 中包含所有这些信息。从技术上讲,您完全回答了我的问题,关于我如何找出问题所在,所以这个问题已关闭。谢谢! 要找出为什么,请查看/bin/sh 使用的rc 文件,很可能是.bashrc 和它来源的其他文件。 我将 ~/.bashrc 设置为 0002 的 umask ......但仍然无法正常工作。在这里查看更多解释:***.com/questions/38801251/…

以上是关于使用git签出文件时如何找出导致文件权限更改的原因?的主要内容,如果未能解决你的问题,请参考以下文章

按文件类型拆分 git 分支或提交

Git:如何从远程分支更新/签出单个文件?

Git如何签出提交进行一些更改并将其推送回相同的提交

用Git记录文件复制操作

Git重置(撤消、丢弃)文件变更

SVN忽略某个文件的更改,并不提交