3

考虑以下情况:

我有一个包含 javascript 项目代码的 git 存储库 foo.git。在此存储库中,有一个分支生产,其中包含由 Web 服务器提供的代码状态,该服务器从/var/www/foo. 此存储库是项目的主存储库。每个人都从/向它推拉。

每当有人推送到该特定分支时,是否可以/var/www/foo更新到生产结帐?您可以假设 git 守护进程(或用户 git,即所有人登录以通过 SSH 连接的用户)有权写入所述目录。

4

3 回答 3

2

您必须使用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,更新将或多或少是原子的。

我经常在生产中使用它,并且与在同一目录上解包相比有一些好处。

  1. 回滚很容易
  2. 您可以在不中断当前部署的情况下执行解包后程序,例如编译或安装依赖项

尖端

  1. 每次更新,附加到部署日志,说明更新发生的时间,以及它们的哈希 id 是什么。这使得回滚容易。
于 2013-02-03T07:11:21.890 回答
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'

您必须设置您的 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
于 2013-02-03T04:18:45.547 回答
0

您可以使用以下命令将 git 存储库签出foo.git到目录中:dir

git archive | tar x dir
于 2013-02-03T13:40:11.420 回答