0

我最近开始在我的日常工作流程中使用 Git,我真的很喜欢使用它。

我在我的 VPS 上名为 website.git 的文件夹下有一个裸在线 repo (git init --bare --shared),并在需要时从本地推送更改,这绝对没问题。现在,当我在本地存储库中保存数据时,我将更改推送到网上,但随后我也必须手动将文件移动到 public_html 文件夹中,正如您可以想象的那样,这真的很痛苦。

我尝试过使用http://toroid.org/ams/git-website-howto中描述的 git 钩子,但它的权限对我不起作用。

public_html 和 website.git 文件夹都归 www-data:developers 所有,但是当 post-receive 钩子启动时,它无法取消链接旧文件,并且任何新文件都自动归 jack:jack 所有,这是我使用 SSH 连接到服务器的用户。

我的 hooks/post-receive 文件是可执行的并且包含:

#!/bin/sh
GIT_WORK_TREE=/home/web/website.com/public_html git checkout -f

我的在线回购存储在

/home/web/website.com/website.git

我究竟做错了什么?

4

2 回答 2

1

这是一个基本的操作系统权限问题:当您用于ssh推送更改时,git 用于ssh连接到远程主机(作为您选择的某些用户——这就是为什么 url 允许 ssh:// user@host /path)所以为了在主机上运行命令,这些命令会拾取被推送的对象(提交、树、blob 和/或标签)并将它们插入到目标 repo 中。不管那个用户是谁,然后也运行钩子。因此,当 post-receive 挂钩运行时,它会以该用户身份运行。

您可以使 public_html 目录更具可写性(以便您的所有git push用户都可以写入);您可以以用户身份登录www-data;或者您可以使用 set-uid 程序以git checkout -fwww-data 用户身份运行,但具有任何 set-uid 程序的所有常见危险。(该sudo命令可以用于最后一种技术。sudo -n -u www-data我想你会想要的,虽然我从来没有真正设置过这种东西。)


注意:我做了一些实验,在目标主机上安装了一个旧的(1.7.0.3)版本的 git。这有一个相对路径失败的错误。为了解决这个问题,这是我最终得到的结果hooks/post-receive(注意,这是非常原始的,因为它不检查推送到的内容):

#! /bin/sh
umask 0 # let everyone have write permission on everything
export GIT_DIR=$(readlink -f $(git rev-parse --git-dir))
export GIT_WORK_TREE=$(readlink -f /tmp/t)
(cd $GIT_WORK_TREE && git checkout -f)

在较新的 git(已修复错误)中,您将不需要上述所有内容(尽管它确实在手动运行时使钩子工作,这很方便)。

于 2012-05-09T10:13:10.153 回答
0

我遇到了与您类似的权限问题,并使用了另一种技术进行部署,但我确实将我的 apache 更改为使用我的 git 用户。它对我git 1.7.9有用Ubuntu 12.04.1 LTSApache/2.2.22

我的 git 用户被调用git,我的 apache 使用了该ubuntu用户。我必须编辑 apache 配置/etc/apache2/conf.d/security(你也可以这样做/etc/apache2/http.conf)以包括:

User git
Group git

现在我/var/www/myproject在推送上部署所有文件,使用git:git用户/组创建文件,我的 apache 使用相同的用户/组运行。

hooks/post-receive您可以随时将其添加到脚本的末尾:

chown -R www-data:developers /home/web/website.com/public_html

现在您只需要重新启动服务器或执行service apache2 restart

于 2012-10-31T18:53:38.087 回答