7

我们的 Git 工作流程的基本设置是本地网络服务器上的一个裸存储库,两个开发人员推/拉到它。

我们希望自动复制(签出)每个被推送到本地网络服务器上不同位置的分支。举例说明:

将“开发”分支副本推送到“开发”子文件夹。将“master”分支副本推送到“master”子文件夹。

我们遇到的问题是让 post-receive 挂钩来执行此操作。这是我们目前拥有的:

#!/bin/bash

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ "master" == "$branch" ]; then
    GIT_WORK_TREE=/master
    git checkout -f $branch
    echo 'Changes pushed master.'
  fi

  if [ "develop" == "$branch" ]; then
    GIT_WORK_TREE=/develop
    git checkout -f $branch
    echo 'Changes pushed to develop.'
  fi
done

收到的错误是:

“远程:致命:此操作必须在远程工作树中运行:更改推送到开发。”

正如您对该错误所期望的那样 - 实际上没有检查任何内容。

我也尝试过以这种方式接收后,但同样的问题:

#!/bin/bash

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ "master" == "$branch" ]; then
    git --work-tree=/master checkout -f $branch
    echo 'Changes pushed master.'
  fi

  if [ "develop" == "$branch" ]; then
    git --work-tree=/develop checkout -f $branch
    echo 'Changes pushed to develop.'
  fi
done

任何人都可以在这里解释我做错了什么(随时像对 3 岁的孩子一样解释它:))。谢谢。

为了让未来的读者更清楚答案,托雷克一针见血。我曾经--work-tree=/master尝试进入我的裸仓库根目录中的一个名为“master”的文件夹(例如,在“分支”、“钩子”等旁边)。一旦我将其更改为--work-tree=./master(注意正斜杠前的点),一切都按我的预期工作。

4

2 回答 2

8

您应该将 'GIT_WORK_TREE=/master git checkout -f $branch' 放在一行中,然后它就起作用了,在阅读了您的帖子后,我收到的邮件是:

#!/bin/sh

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ "master" == "$branch" ]; then
    GIT_WORK_TREE=/home/tnj/www/www.test.com git checkout -f $branch
    chmod -R 775 /home/tnj/www/www.test.com/
    echo 'changes pushed to www.test.com'
  fi

  if [ "develop" == "$branch" ]; then
    GIT_WORK_TREE=/home/tnj/www/www.test.com.dev git checkout -f $branch
    chmod -R 775 /home/tnj/www/www.test.com.dev/
    echo 'changes pushed to www.test.com.dev'
  fi
done

效果很好,谢谢你的帖子!:)

于 2014-12-16T02:30:32.570 回答
3

你得到这个是因为/master并且/develop是不存在的目录:

$ git --work-tree=/nonexistent checkout master
fatal: This operation must be run in a work tree

您可能还想查看我对有关此方法出现的另一个问题的问题的回答,该方法还解决了您从流行但错误的接收后技术中复制的一个小错误(cut用于解析更新的参考)。

--bare[您的措辞也让我想知道您是否正在考虑将这两个分支部署到正在接收推送的(大概)存储库中的子目录中。这可能不是一个好主意。]

另一种(不同的)部署方法是在部署位置拥有一个“真正的”git 树。然后,而不是git --work-tree=... checkout你做这样的事情:

deploy()
{
    local path=$1 branch=$2

    (cd $path && unset GIT_DIR && git fetch && git checkout -f origin/$branch)
}

(未经测试,随意尝试和/或修改)。这在磁盘空间和更新窗口(我在另一个答案中提到)方面有其他稍微不同的权衡。

于 2013-10-09T11:57:38.660 回答