考虑以下情况:
我有一个包含javascript项目代码的git存储库foo.git。在此存储库中有一个分支 production ,其中包含由Web服务器提供的代码状态,该服务器从/var/www/foo
获取代码。此存储库是项目的主存储库。每个人都推着/拉出它。
每当有人推送到特定分支时,是否可以将/var/www/foo
更新为 production 的结帐?您可以假设git守护程序(或用户所有人登录以通过SSH连接的用户git)有权写入所述目录。
答案 0 :(得分:2)
您必须使用git init --bare
在服务器上创建一个裸存储库。
然后使用post-receive
挂钩来触发部署。
您的部署方式取决于您。
我通常会放置一个deploy
导演,在某个地方合乎逻辑。
然后每次结账时,我将最新的分支解压缩到deploy/COMMIT_ID
,其中COMMIT_ID
是最新推送的散列。结帐完成后,您可以将符号链接重新指向最新的部署目录。
我通常的目录结构:
deploy.git/
deploy/
a7922231/
b2f0a2af/
latest -> b2f0a2af
我通常使用git-checkout
将分支解压缩到目录中,而不是使用git-archive
。
# Assuming current directory is deploy.git
HEAD=`cat refs/heads/master`
mkdir -p ../deploy/${HEAD}
git archive master | tar -x -C ../deploy/${HEAD}
您的网络服务器可以指向deploy/latest
,更新将或多或少是原子的。
我经常在制作中使用它,并且比在同一目录中解压缩有一些好处。
答案 1 :(得分:1)
您必须在post-receive
中创建一个名为/git/foo.git/hooks directory
的文件(基于我上面的评论)。像这样(有一些调试日志):
#!/bin/sh
echo 'Hook called'
pullneeded=false
while read oldrev newrev refname
do
echo "OLDREV $oldrev NEWREV $newrev REFNAME $refname"
if [ "$refname" == "refs/heads/production" ]; then
echo 'Pull needed'
pullneeded=true
fi
done
if [ $pullneeded ]; then
echo 'Pull'
cd /var/www/foo
git --git-dir=/var/www/foo/.git pull
fi
echo 'Hook done'
您必须在/var/www/foo
设置git存储库以跟踪其他存储库的 production 分支。如果它被称为 origin 那么它就是:
git branch --set-upstream production origin/production
当然, production 分支必须在/var/www/foo
存储库中签出。
<强>已更新强>
也许post-update
挂钩更合适(样本来自此处https://stackoverflow.com/a/6597728/299788):
#!/bin/bash
case " $* " in
*' refs/heads/production '*)
cd /var/www/foo
git --git-dir=/var/www/foo/.git pull
;;
esac
答案 2 :(得分:0)
您可以使用以下命令将git存储库foo.git
签出到目录dir
中:
git archive | tar x dir