Gitolite 和存储在一台服务器上的 Web 服务器。目录 /var/www/site
是存储库“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
所有工作都完美,但在“pull ”所有更新或新文件后,所有者将更改为 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
最佳答案
正如 @ThiefMaster 所说,您无法像这样更改文件所有权,但有一种不同的方法可以解决该问题。
当您从某个开发系统(可能与部署系统相同的系统,也可能是其他系统)推送并使用 gitolite 进行访问时,您将推送到 ssh://git@server/repo
(或某些 URL 变体,但无论如何,使用 ssh 到 gitolite 服务器计算机,以用户 git
身份登录该服务器计算机 - 我们的设置为以 身份登录gitolite
但根据您的问题,您正在使用用户 git
)。不过,除了身份验证的工作方式之外,从服务器的角度来看,“developer@dev-host 推送给我,用户 git”实际上与“我,用户 git,从developer@dev-host pull ”相同。这就是为什么在 post-receive Hook 中,当您运行 cd/var/www/site && git pull origin master 等命令时,新文件由用户 git 拥有:用户 git merge 到“他的”本地存储库,然后在另一个存储库上执行 cd
和 git pull
步骤。
developer@dev-host
能够 ssh 进入 git@server
的首要原因是该服务器的 ~git/.ssh/authorized_keys
code> 文件包含 developer@dev-host
的公钥(通过 gitolite 的管理存储库以及添加用户 key 时它应用的各种魔法)。因此,假设用户 git@server
有自己的 ssh key 对,假设您希望 /var/www/site
由用户 www 拥有-站点
。然后,如果用户 www-site
有一个主目录(可能是 /var/lib/www-site
)并且该主目录有一个 .ssh/authorized_keys
文件授权用户 git
的 key ,然后用户 git
可以作为用户 www-site
进行 ssh 访问。然后,您的更新后 Hook 将执行如下操作:
#! /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
(我添加了代码来识别两个特定分支并仅对这些分支进行更新。注意:这些都没有经过测试。)
关于git - 执行更新后 Hook 后如何更改所有者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12918887/