2011-09-22 55 views
2

目前我一个项目部署到生产使用Git,使用git push production master到资源库具有以下后收到钩:部署一个网站,以多种环境使用Git

#!/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上一个新的存储库,具有相似的后收到钩(与/myproject-alternate/更换/myproject/),加入这个新的存储库git remote add alternate ssh://server/home/username/projects/myproject-alternate.git。现在我可以使用git push alternate branchname:master部署到备用路径。

这工作,但我有一些问题:

  1. 的命令部署到备用服务器是不是我所期待的,不止一次,我忘了:master末和服务器的存储库收到新分支和post-receive挂钩未被触发。
  2. 我不确定在服务器上创建新的存储库是否是最佳解决方案,我不知道大型项目会发生什么情况。

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

回答

2

我已经写了一个blog post关于我用来部署我的网站到临时服务器和现场服务器的设置。你可以做类似的事情。关键是配置你要在.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分支。

但是,由于您的备用和生产工作树位于同一台计算机上,因此只需创建一个存储库并将其检出到两个不同的位置即可。要做到这一点,忽略前款规定的,而是把这样的事情在你的后收到钩:

#!/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分支,它都将更新生产工作树,并且无论何时按下分支,它都将更新替代工作树。

声明:我没有真正测试过,所以先在测试文件夹中试试。如果我发现任何错误,我会回来编辑。

+0

在测试之前,您能否解释'branch = $ {3 ## * /}'行? – dipnlik

+0

它删除匹配模式'* /'的最长前导子字符串。 –

+0

...从哪个字符串? (抱歉再次提问,我真的很想了解整行代码,并且我不能Google上有这么多符号的东西) – dipnlik

0

我也写过a blog post我使用的设置,它允许我的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 .. 
} 

在远程,创建一个存储库:

$ 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>/