2011-09-22 53 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>/