2

目前,我使用 git 将项目部署到生产环境,使用git push production master具有以下接收后挂钩的存储库:

#!/bin/bash
GIT_WORK_TREE=/home/username/www.example.com/myproject/ git checkout -f

production是一个遥控器,通过添加git remote add production ssh://server/home/username/projects/myproject.git

但是现在我需要将一个单独的分支部署到服务器上的一个单独路径。我确实想出了一个解决方案,但我想有更好的方法来做到这一点。

我所做的是在服务器上创建一个新存储库myproject-alternate.git,使用类似的 post-receive 钩子(替换/myproject//myproject-alternate/),将这个新存储库添加为git remote add alternate ssh://server/home/username/projects/myproject-alternate.git. 现在我可以使用git push alternate branchname:master.

这有效,但我有一些问题:

  1. 部署到备用服务器的命令不是我所期望的——不止一次我忘记了:master最后的命令,服务器的存储库收到了一个新的分支,并且没有触发 post-receive 钩子。
  2. 我不确定在服务器上创建一个新的存储库是否是最好的解决方案,我想知道一个更大的项目会发生什么。

是否有其他方法可以在没有上述问题的情况下完成此部署流程?也许一个更好的 post-receive 钩子使用接收到的分支名称来部署到正确的路径?(这甚至可能吗?)

4

2 回答 2

2

我写了一篇关于我用来将我的网站部署到登台服务器和实时服务器的设置的博客文章。你可以做类似的事情。关键是配置您将要推送到.git/config本地存储库文件中的分支,如下所示:

[remote "alternate"]
    url = ssh://server/home/username/projects/myproject-alternate.git
    fetch = +refs/heads/master:refs/remotes/alternate/master
    pushurl = ssh://server/home/username/projects/myproject-alternate.git
    push = refs/heads/branchname:refs/heads/master
[remote "production"]
    url = ssh://server/home/username/projects/myproject.git
    fetch = +refs/heads/master:refs/remotes/production/master
    pushurl = ssh://server/home/username/projects/myproject.git
    push = refs/heads/master:refs/heads/master

这将设置它,以便每当您键入

git push alternate

它会自动将本地branchname分支推送到备用存储库中的远程master分支。

但是,由于您的备用工作树和生产工作树位于同一台计算机上,您可能只需创建一个存储库并将其检出到两个不同的地方即可。要做到这一点,忽略上一段,而是在你的 post-receive 钩子中放置这样的东西:

#!/bin/bash
checkout_alt=
checkout_prod=
while read oldrev newrev refname; do
    case "$refname" in
        ( "refs/heads/branchname" )
            export checkout_alt=1 ;;
        ( "refs/heads/master" )
            export checkout_prod=1 ;;
    esac
done
test -n "$checkout_alt" && GIT_WORK_TREE=/home/diazona/tmp/gittest/alt/ git checkout -f branchname
test -n "$checkout_prod" && GIT_WORK_TREE=/home/diazona/tmp/gittest/prod/ git checkout -f master

(显然你不必使用if声明)。如果你这样做,我建议让存储库裸露,这样它就不会存储自己的工作副本,只是为了简单起见。这样一来,你只需要一个遥控器,每当你推送master分支时,它就会更新生产工作树,而每当你推送branchname分支时,它就会更新备用工作树。

免责声明:我还没有实际测试过,所以先在测试文件夹中尝试一下。如果我发现任何错误,我会回来编辑。

于 2011-09-22T02:10:36.823 回答
0

我还写了一篇关于我使用的设置的博客文章,它允许我将git push项目中的每个分支一直到我的远程,将每个分支部署到各自的目录中。

例如:

Branch      | Directory on remote
--------------------------------------
master      | /www/foo.com/master
staging     | /www/foo.com/staging
production  | /www/foo.com/produciton

因此,为此,请将以下函数添加到您的服务器点文件中:

function gitorigin() {
    mkdir -p "$1"
    cd "$1"
    git init --bare
    git config core.bare false
    git config receive.denycurrentbranch ignore
    cat <<EOF >hooks/post-receive
#!/bin/bash

while read oldrev newrev ref
do
    branch=\`echo \$ref | cut -d/ -f3\`
    mkdir -p ../\$branch
    git --work-tree=../\$branch checkout -f \$branch
    echo Changes pushed to \$branch
done
EOF
    chmod +x hooks/post-receive
    cd ..
}

在 Remote 上,创建一个存储库:

$ cd /www/foo.com
$ gitrepo foo.git

在本地,推送一个分支

$ cd ~/Sites/foo.com
$ git remote add origin ssh:///<USER>@<HOST>/www/foo.com/foo.git
$ git push origin <BRANCH>

会将您的主分支推送到远程,进入/www/foo.com/<BRANCH>/.

于 2013-09-02T16:12:47.703 回答