5

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

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 管理网站时,是否有一种不同的、干净的方式来区分测试和生产部署?

作为根据 Vi 的回答的附加说明,是否有一种很好的方法可以处理删除而不会对文件系统造成太多影响?

谢谢你,-沃尔特

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 中的存储库(这些是“裸”存储库,在 init 之后添加了工作树)具有基本的后接收:

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

3 回答 3

2

认为这两种方式都会奏效。

您还可以使用“git archive master | tar -C c:/temp/BLAH -x”和“git archive live-site | ssh live-site 'tar -C /var/www -x'”。

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

在测试“测试”版本后,是否应该手动触发实时站点更新?

于 2010-02-05T18:57:02.317 回答
1

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

当然是。这是一个非常罕见的情况,您希望您的测试站点托管在您的生产站点旁边。这几乎在所有方面都是危险和不专业的,更不用说数据库损坏、网络服务器锁定等。

我通常有一个用于测试目的的 VM 设置。效果很好,我可以在旅行时将它放在我的笔记本电脑上。

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

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

于 2010-02-14T09:44:54.593 回答
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 服务器)进行更改但忘记提交它们。使用checkoutwith-f将丢弃这些更改。这个钩子是防止这种情况发生的好地方,但如果在拉取之前在远程服务器上也调用了一个钩子,这样您就可以无缝地接收这些更改。

接收后

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

关于有两个分支,我认为您的第一个解决方案比处理多个存储库更优雅。如果你真的想让你的生产站点保持隔离,你可以在本地使用 rsync ,它具有类似的增量补丁。我将在存储库中有一个测试和稳定的分支,只有测试站点作为工作目录。当准备好发布时,将测试合并到稳定分支,推送,并有一个钩子来寻找稳定分支的提交,然后调用 rsync。

于 2010-04-10T01:46:46.020 回答