考虑以下情况:
我有一个包含 javascript 项目代码的 git 存储库 foo.git。在此存储库中,有一个分支生产,其中包含由 Web 服务器提供的代码状态,该服务器从/var/www/foo
. 此存储库是项目的主存储库。每个人都从/向它推拉。
每当有人推送到该特定分支时,是否可以/var/www/foo
更新到生产结帐?您可以假设 git 守护进程(或用户 git,即所有人登录以通过 SSH 连接的用户)有权写入所述目录。
您必须使用git init --bare
. 然后使用post-receive
钩子触发您的部署。如何部署取决于您。
我通常会在deploy
合乎逻辑的地方安排一个导演。然后每次结帐,我将最新的分支解压到最新推送的哈希deploy/COMMIT_ID
所在的位置。COMMIT_ID
签出完成后,您可以将符号链接重新指向最新的部署目录。
我常用的目录结构:
deploy.git/
deploy/
a7922231/
b2f0a2af/
latest -> b2f0a2af
git-checkout
我通常不使用 a ,而是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
,更新将或多或少是原子的。
我经常在生产中使用它,并且与在同一目录上解包相比有一些好处。
您必须创建一个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'
您必须设置您的 git 存储库/var/www/foo
以跟踪其他存储库的生产分支。如果它在那里被称为起源,那么它是:
git branch --set-upstream production origin/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
您可以使用以下命令将 git 存储库签出foo.git
到目录中:dir
git archive | tar x dir