当我推送到服务器时,Git正在改变我的文件权限

时间:2012-06-27 15:45:41

标签: git permissions file-permissions

我正在使用git来管理服务器上的网站。

我有一个本地存储库,如下所示

local@workstation:myapp$ ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf("%0o ",k);print}'
total 16
755 drwxr-xr-x@ 18 thomas  staff   612 Jun 13 15:35 application
755 drwxr-xr-x@ 11 thomas  staff   374 Jun 12 16:25 assets
644 -rw-r--r--@  1 thomas  staff  6399 Jun 22 11:45 index.php
755 drwxr-xr-x@ 10 thomas  staff   340 May 14 15:22 system

我在服务器上有一个裸存储库,使用post-receive将存储库指向apache前面。 Apache的public文件夹内容在下面 - 不是裸存储库。

root@server:/srv/public/myapp# ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf("%0o ",k);print}'
total 20
700 drwx------ 15 root root 4096 Jun 27 11:31 application
700 drwx------ 10 root root 4096 Jun 27 11:31 assets
600 -rw-------  1 root root 6399 Jun 27 11:31 index.php
700 drwx------  8 root root 4096 Jun 27 11:31 system

这会对网络服务器上的代码造成混乱。

我该如何解决这个问题?如果这有任何区别,我正在使用gitolite。

git服务器配置文件

[core]
        repositoryformatversion = 0
        filemode = true
        bare = true

2 个答案:

答案 0 :(得分:26)

This thread post提供了一个非常好的解释:

  

这是设计的。虽然git数据结构可以在技术上存储   在它的树中使用unix模式位,它是在git的历史早期发现的   尊重超出简单可执行位的任何东西最终成为了   对于git的正常使用情况(即存储代码的人)来说更麻烦   或存储库中的其他共享文件。)

     

我们可以添加一个配置选项来尊重文件模式,但它有   一般被认为是不值得的。它只解决了一部分问题   一般元数据问题,因为它省略了所有者和组名称或ID,如   以及像ACL这样的扩展元数据。

     

如果模式对您很重要,建议的修复方法之一是:

     
      
  1. 使用可以从git hooks调用的“metastore”之类的工具    将在跟踪的文件中保存和恢复文件权限    存储库。请注意,使用这样的工具时会有比赛    保护文件的条件(即,git将创建您的文件为    644,然后Metastore将其校正为600;同时,    有人可以阅读你的文件。)

  2.   
  3. 根据您存储的确切内容,保留可能是有意义的    您的存储库位于另一个目录中,受权限保护,以及    然后使用单独的工具从存储库中部署文件    到他们的最终位置(例如,Makefile或其他安装    工具)。

  4.   

答案 1 :(得分:1)

要扩展@ThomasReggi的注释,该注释可以解决通过git部署时更改权限的问题,因此我保留了已实现的解决方案。 您可以在hooks /接收后文件(或您使用的任何钩子)中添加命令

在使用git命令--work-tree =(执行部署的行)行之前,添加一些“ echo”和当前umask的显示,以及正确执行部署所必需的umask设置,然后再次执行显示当前的umask以确认更改。 (这样可以在执行部署时看到它(调试))

echo "Ref $ ref received. Deploying $ {BRANCH} branch to production ..."
# SHOW current uMask
echo "Current uMASK:"
umask
echo "Set uMASK to 0022"
umask 0022
echo "New uMASK seted to ..."
umask
echo "end umask conf"

# deploy
HUB_VERBOSE = 1
git --work-tree = $ TARGET --git-dir = $ GIT_DIR checkout -f

这样,仅在当前会话中更改umask,而不会影响其余的ssh连接。并在创建/修改文件时以必要的权限来部署文件,而不是在部署后使用命令来重新设置必要的权限,从而导致应用程序在应用适当的权限期间失败。 >

如果您的权限问题影响了您的php应用程序,则此问题似乎与您运行php(DSO,suPHP,suEXEC)的方式有关,因为它们每个人都需要不同的权限设置才能正确运行。如果您是从服务器迁移的,或者更改了php处理程序,则可能会遇到此问题。