2

Gitolite 和存储在一台服务器上的 Web 服务器。目录/var/www/site是回购“站点”的克隆。Git 用户包含在组 www-data 中。我有/home/git/repositories/site.git/hooks/post-update hook

#!/bin/sh    
unset GIT_DIR
cd /var/www/site && git pull origin master

一切正常,但在“拉”所有更新或新文件后将所有者更改为 git:git。我不知道如何在没有 root 用户权限的情况下更改所有者。有什么建议么?

我找到了很好的方法(更新后):

#!/bin/sh

PATH=/usr/bin:/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
PROJECT="projectname"
GIT_URL="http://factory.domain.ru/git"

git update-server-info

if [ ! -f $1 ]; then
    exit 0
fi

while [ -n "$1" ]
do
    REF=`echo $1 | awk --field-separator="/" '{print $2}'`
    if [ $REF = "branches" -o $REF = "heads" ]; then
        BRANCH=`echo $1 | awk --field-separator="/" '{print $3}'`

        if [ ! -d /srv/www/$PROJECT/repo/master ]; then
            mkdir -p /srv/www/$PROJECT/repo
            GIT_SSL_NO_VERIFY=true git clone $GIT_URL/$PROJECT /srv/www/$PROJECT/repo/master
        fi

        if [ ! -d /srv/www/$PROJECT/repo/$BRANCH ]; then
            GIT_SSL_NO_VERIFY=true git clone -b $BRANCH $GIT_URL/$PROJECT /srv/www/$PROJECT/repo/$BRANCH
        else
            cd /srv/www/$PROJECT/repo/$BRANCH
            GIT_SSL_NO_VERIFY=true git fetch origin
            GIT_SSL_NO_VERIFY=true git reset --hard origin/$BRANCH
            GIT_SSL_NO_VERIFY=true git clean -d -f
            GIT_SSL_NO_VERIFY=true git checkout
            GIT_SSL_NO_VERIFY=true git pull
        fi
    fi
    shift
done

和“更新”:

#!/bin/sh

refname="$1"
oldrev="$2"
newrev="$3"

PROJECT="projectname"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
        echo "Don't run this script from the command line." >&2
        echo " (if you want, you could supply GIT_DIR then run" >&2
        echo "  $0 <ref> <oldrev> <newrev>)" >&2
        exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
        echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
        exit 1
fi

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
        newrev_type=delete
else
        newrev_type=$(git cat-file -t $newrev)
fi

BRANCH=`echo $1 | awk --field-separator="/" '{print $3}'`

delete () {
    mv /srv/www/$PROJECT/repo/$BRANCH /srv/www/$PROJECT/repo/$BRANCH.removed_by_git
    rm -rf /srv/www/$PROJECT/repo/$BRANCH.removed_by_git
}

case "$refname","$newrev_type" in
        refs/heads/*,delete)
                # delete branch
                delete
                ;;
        refs/remotes/*,delete)
                # delete tracking branch
                delete
                ;;
esac

exit 0

habrahabr.ru

4

3 回答 3

1

您不能不授予用户 root 访问权限 - 但是,您可以这样做,sudo因此他只能更改该文件夹的所有者。

以这种方式配置 sudo 后,您可以简单地添加sudo chown -R www-data:www-data /var/www/site到钩子中。

于 2012-10-16T16:14:55.643 回答
1

正如@ThiefMaster 所说,您不能像那样更改文件所有权,但是有一种不同的方法可以解决这个问题。

当您从某个开发系统(可能与部署系统相同的系统,也可能是其他系统)推送并使用 gitolite 进行访问时,您正在推送到ssh://git@server/repo(或某些 URL 变体,但无论如何,使用 ssh 到 gitolite 服务器机器,以用户git身份登录该服务器机器 - 我们设置为登录,gitolite但基于您使用的问题 user git)。但是,除了身份验证的工作方式之外,从服务器的角度来看,“developer@dev-host 推送给我,用户 git”实际上与“我,用户 git,从 developer@dev-host 拉取”相同。这就是为什么在你的 post-receive 钩子中,当你运行类似cd /var/www/site && git pull origin master的命令时,新文件由 user 拥有git:它是用户 git 合并到“他的”本地 repo,cdgit pull踏上另一个回购。

developer@dev-host首先可以 ssh 进入的原因git@server是服务器的~git/.ssh/authorized_keys文件包含公钥developer@dev-host(通过 gitolite 的管理存储库以及添加用户密钥时应用的各种魔法)。所以,假设 usergit@server有他自己的 ssh 密钥对,假设你想/var/www/site被 user 拥有www-site。然后,如果用户www-site有一个主目录(/var/lib/www-site也许)并且该主目录有一个.ssh/authorized_keys授权用户git密钥的文件,那么用户git可以作为用户 ssh 进入www-site。然后,您的更新后挂钩将执行以下操作:

#! /bin/sh

# update running copy on real host
update_master() {
    ssh www-site@server "cd /var/www/site && git pull origin master"
}

# update test copy on test host
update_test() {
    ssh www-site@testhost "cd /var/www/site && git pull origin test"
}

for ref do
    case "$ref" in
    refs/heads/master) update_master;;
    refs/heads/test) update_test;;
    *) ;; # ignore other branches
done

(我添加了代码来识别两个特定的分支并只为这些分支进行更新。注意:这些都没有经过测试。)

于 2012-10-17T12:29:40.073 回答
0

# su requireduser -c 'git pull origin branch'

于 2017-04-06T11:29:27.040 回答