Git for Websites / post-receive / Separation of Test and Production Sites

时间:2010-02-02 18:02:46

标签: git web git-post-receive website-deployment

我正在使用Git来管理我的网站的源代码和部署,目前在同一个盒子上运行测试和实时网站。最初使用此资源http://toroid.org/ams/git-website-howto后,我想出了以下post-receive钩子脚本,以区分推送到我的实时网站并推送到我的测试网站:

while read ref
do
  #echo "Ref updated:"
  #echo $ref -- would print something like example at top of file
  result=`echo $ref | gawk -F' ' '{ print $3 }'`
  if [ $result != "" ]; then
    echo "Branch found: "
    echo $result
    case $result in
      refs/heads/master )
        git --work-tree=c:/temp/BLAH checkout -f master
        echo "Updated master"
        ;;
      refs/heads/testbranch )
        git --work-tree=c:/temp/BLAH2 checkout -f testbranch
        echo "Updated testbranch"
        ;;
      * )
        echo "No update known for $result"
        ;;
    esac
  fi
done
echo "Post-receive updates complete"

然而,我怀疑这实际上是安全的:)我绝不是Git专家,但我猜测Git可能跟踪当前检出的分支头,这种方法可能具有潜力把它混为一谈。

所以有几个问题:

  1. 这样安全吗?

  2. 更好的方法是将我的基础存储库作为测试站点存储库(具有相应的工作目录),然后将该存储库推送更改为新的实时站点存储库,该存储库具有相应的工作目录。现场基地?这也允许我将生产移动到不同的服务器并保持部署链完好。

  3. 有什么我想念的吗?在使用Git管理网站时,是否有不同的,简洁的方法来区分测试和生产部署?

  4. 根据Vi的回答,作为一个额外的说明,是否有一个很好的方法可以处理删除而不会破坏文件系统?

    谢谢你, -Walt

    PS - 我为多重回购提出的脚本(除非我听到更好,否则我正在使用)如下:

    sitename=`basename \`pwd\``
    
    while read ref
    do
      #echo "Ref updated:"
      #echo $ref -- would print something like example at top of file
      result=`echo $ref | gawk -F' ' '{ print $3 }'`
      if [ $result != "" ]; then
        echo "Branch found: "
        echo $result
        case $result in
          refs/heads/master )
            git checkout -q -f master
            if [ $? -eq 0 ]; then
                echo "Test Site checked out properly"
            else
                echo "Failed to checkout test site!"
            fi
            ;;
          refs/heads/live-site )
            git push -q ../Live/$sitename live-site:master
            if [ $? -eq 0 ]; then
                echo "Live Site received updates properly"
            else
                echo "Failed to push updates to Live Site"
            fi
            ;;
          * )
            echo "No update known for $result"
            ;;
        esac
      fi
    done
    echo "Post-receive updates complete"
    

    然后在../Live/$sitename中的repo(这些是在init之后添加工作树的“裸”回购)具有基本的post-receive:

    git checkout -f
    if [ $? -eq 0 ]; then
        echo "Live site `basename \`pwd\`` checked out successfully"
    else
        echo "Live site failed to checkout"
    fi
    

3 个答案:

答案 0 :(得分:2)

认为两种方式都有效。

你也可以使用“git archive master | tar -C c:/ temp / BLAH -x”和“git archive live-site | ssh live-site'tar -C / var / www -x'”。< / p>

保持单独的存储库可能很有用,但“推入另一个与推送相关的钩子”看起来很棘手,我希望它很慢。一种缓慢而脆弱的长链。

可能是实时网站更新应该在测试“测试”版本后手动触发吗?

答案 1 :(得分:1)

  

更好的方法是拥有我的   base repository是测试站点   存储库(具有相应的工作   目录),然后有   存储库推送更改为新的实时   站点存储库,它有一个   相应的工作目录   现场基地?这也可以   我将生产转移到了   不同的服务器并保持   部署链完好无损。

肯定是的。这是一个非常罕见的场合,您希望您的测试站点就位于您的生产站点旁边。几乎在所有方面都是危险和不专业的,不是谈论数据库损坏,网络服务器锁定等。

我通常会进行VM设置以进行测试。工作得非常好,我可以在旅途中随身携带笔记本电脑。

使用git部署您的网站是一个非常好的主意,还有很多其他人这样做(例如Rob Conery)。如果您碰巧有一个实时和测试站点,您应该在您的存储库中为它们分别设置分支,并在相应的服务器存储库上设置为远程跟踪分支。您的工作流程就像在测试分支中工作一样简单,将其推送到测试,测试,合并到实时和推送。

老实说,不要让自己太难。

答案 2 :(得分:1)

我也在toroid.org上遵循了相同的指南,但是我想要注意的是,尽管你开始使用裸存储库,但通过添加工作目录,很可能需要额外的处理。我发现,如果您的内容可能会动态或以其他方式发生变化并且在使用git checkout -f

时不想丢失数据,则以下挂钩非常有用

预接收

#!/bin/sh
git add -A
git diff --quiet --cached
if [ $? -gt 0 ]; then
    git commit --quiet -m "autocommit"
    echo "Working Directory was out of sync. Pull to receive updated index."
    exit 1
fi

如果远程工作目录中有更改,这将停止推送。将其视为某人(Web服务器)进行更改但忘记提交它们。将checkout-f一起使用会放弃这些更改。这个钩子是防止这种情况发生的好地方,但是如果在拉动之前在远程服务器上也有一个挂钩,那么你就可以无缝地接收这些更改。

后接收

#!/bin/sh
git checkout -f
echo "Working directory synced."

关于有两个分支,我认为你的第一个解决方案比处理多个存储库更优雅。如果您确实希望将生产站点隔离,则可以在本地使用具有类似增量修补的rsync。我会在存储库中有一个测试和稳定的分支,只有测试站点作为工作目录。当准备发布时,将测试合并到stable分支中,push,并有一个钩子查找提交到stable分支的调用rsync。