2012-06-05 57 views
2

問題:如果工作樹不是裸露的,我如何將我的本地提交推送到我的開發服務器?使用git + post-receive hook管理網站:錯誤推送更改

我的情況:

  1. 我設置的git我的開發服務器上,這樣,當我推的局部變化,它們被添加到一個分離的工作樹(如described here和很像this post)。
  2. 然後我遇到了在dev服務器上運行git的問題(例如,git status),因爲git找不到工作樹。
  3. 我詢問了SO和got the tip off,我需要在我的配置文件中設置bare = false並指定工作樹。甜。

但現在,當我試圖把我提交到開發服務器我得到這個錯誤:

$ git push origin master 
[email protected]'s password: 
Counting objects: 26, done. 
Delta compression using up to 4 threads. 
Compressing objects: 100% (18/18), done. 
Writing objects: 100% (18/18), 2.56 KiB, done. 
Total 18 (delta 8), reused 0 (delta 0) 

remote: error: refusing to update checked out branch: refs/heads/master 
remote: error: By default, updating the current branch in a non-bare repository 
remote: error: is denied, because it will make the index and work tree inconsistent 
remote: error: with what you pushed, and will require 'git reset --hard' to match 
remote: error: the work tree to HEAD. 
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to 
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into 
remote: error: its current branch; however, this is not recommended unless you 
remote: error: arranged to update its work tree to match what you pushed in some 
remote: error: other way. 
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set 
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'. 

To ssh://[email protected]/xxx/xxx/xxxxxx.git 
! [remote rejected] master -> master (branch is currently checked out) 
error: failed to push some refs to 'ssh://[email protected]/xxx/xxx/xxxxxx.git' 

我看到this other user had the same problem。不幸的是,爲他工作的解決方案是在他的配置中設置了bare = true,這將重新創建我在上面的第3步中遇到的問題。

錯誤消息說

You can set 'receive.denyCurrentBranch' configuration variable to remote: error: 'ignore' or 'warn'

對我來說,是它確定爲我做到這一點?這聽起來不錯,但我沒有足夠的熟悉混帳尚未承認一個壞主意,當談到身邊......

編輯

只是要清楚,我已經添加了一個帖子接收鉤並且工作順利。問題是我似乎不得不在bare=true(並能夠推送到dev服務器)和bare=false(並且能夠在dev服務器上運行git命令)之間進行選擇。

回答

0

我已經摸索出瞭解決方案,是可以接受的,但不是很理想。基本上,我只是通過編輯我的配置文件來避開這個問題,當我需要將更改發送到我的活動服務器時。

配置文件,它允許開發者本地更改推到開發:

[core] 
     repositoryformatversion = 0 
     filemode = true 
     bare = true 

配置文件推dev的變化時,住:

[core] 
     repositoryformatversion = 0 
     filemode = true 
     bare = false 
     worktree = /var/www/example.com/httpd/ 

優點

  1. 作品
  2. 有一次,我已經改變了配置文件推住,回購被「鎖定」和其他開發商無法更改推
  3. 不是一個巨大的問題,因爲我需要登錄到dev處理數據庫遷移反正

缺點:基本上只是如果我知道如何正確地做到這一點,我肯定可以實現自動化。

注意:我喜歡@ vonC建議設置post-recieve掛鉤以有條件地推送到活動服務器。對接收後的鉤子進行更改非常簡單,但我不明白鉤子會響應的觸發器是什麼。我很樂意聽到建議,但:)

+0

真的嗎?現在是1歲。我敢打賭你終於設置了裸回購。大概應該接受VonC的答案吧! :P – cregox

2

爲什麼不:

  • 推你提交到裸回購
  • 設置 - 接收後對dev的回購鉤,然後將去非裸開發回購和檢出右支,從裸回購拉動新的提交?

這就是​​描述(與分離工作樹),不過這臺鉤在裸露的回購協議:

$ mkdir /var/www/www.example.org 
$ cat > hooks/post-receive 
#!/bin/sh 
GIT_WORK_TREE=/var/www/www.example.org git checkout -f 
$ chmod +x hooks/post-receive 
+0

我已經做到了這一點,它工作得非常好。問題是我需要能夠登錄到這個開發服務器和(當它處於一個穩定的位置時),使用git將開發文件推送到客戶端可以看到它們的登臺服務器。 就像第三個項目符號所說,我無法在開發服務器上運行任何git命令,直到我設置bare = false。因此,我catch22。有什麼想法嗎? – doub1ejack

+0

@ doub1ejack如果你的post-receive鉤子也會根據自定義標準推到你的升級回購(來自* bare *'dev'回購)? – VonC

+0

這可能是一個不錯的選擇。我不確定我的選項是在創建「自定義條件」以啓動分階段推送。這種方法*是否需要*從本地主機推送?理想情況下,我們不會推動開發階段,直到dev已經過測試並且穩定。在那一點上,我們並不想推動變化,我們希望將該代碼的快照移到分段。 – doub1ejack

0

與倉庫工作是不是你想要做什麼。你需要在你的dev服務器上的裸存儲庫中有一個post-receive鉤子,它可以爲你的web服務器的目錄做一個git checkout-index。這樣,它只是文件。您不必擔心它是否是裸倉庫,是否有工作樹或任何其他與git相關的工具。

喜歡的東西git checkout-index -f -a --prefix=/var/www/htdocs/mywebsite/(注意斜槓 - 這一點很重要)

-f標誌將強制所有現有文件的覆蓋和-a標誌將包括所有文件。

0

你只需要小心你想要做什麼。

git status用於告訴你工作樹的狀態。這對你的情況不應該有用。

另一方面,git push在裸倉庫上是完全有效的。這應該適合你。

如果你想看看變化,你可以用git diff。您只需指定兩個散列git diff $oldref $newref

如果要列出在特定提交中更改的文件,請使用git show --pretty="format:" --name-only $newref

如果要列出一個文件的內容使用git show $newref -- $filepath

+0

好點,謝謝。對於git來說相對來說比較陌生,我認爲我可以使用'git status'作爲測試來看看git是否「有效」,但顯然這太簡單了。 – doub1ejack