我使用 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
有帮助吗?

解决方案

更好的方法是让我的基本存储库成为测试站点存储库(带有相应的工作目录),然后将存储库推送到新的实时站点存储库,该存储库具有与实时站点基础的相应工作目录?这也使我能够将生产转移到另一台服务器并保持部署链完整。

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

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

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

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

其他提示

认为这两种方法都会起作用。

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

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

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

我也遵循了 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,它具有类似的增量修补功能。我将在存储库中有一个测试和稳定分支,仅将测试站点作为工作目录。当准备好发布时,将测试合并到稳定分支中,推送,并使用一个钩子来查找对稳定分支的提交,从而调用 rsync。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top