2011-05-12 229 views
6

我現在每天都在使用git,而這次我遇到了一個我可以這樣描述的問題。「Layering」git存儲庫

我有一個存放整個網站結構的倉庫,web根目錄位於倉庫的根目錄。一切都很好,直到這是一個單一網站的存儲庫。然而,同一個回購現在用於幾個網站 - 基本上是相同的網站,用不同的語言,小模板調整,不同的圖形等等。這些東西自然是版本化的。

有一個主分支,它擁有該網站的原始源代碼,並且我想讓主(或其他分支)擁有在所有網站中通用的代碼,因爲最終會發生變化特定於特定場所以包含在回購的通用部分中。

接下來,每個使用此源代碼的站點都有一個分支。所有這些分支(例如,站點1,站點2站點3)都是從主分支創建的,並且每個站點都克隆了正確的分支。

嗯,這似乎是一個好主意,直​​到我開始到處進行更改。

如果我在site1分支上進行了更改,並且我需要將該更改複製到site2分支,我會從一個分支挑選提交到另一個分支。合併不存在,因爲site1分支上有其他更改,它們不屬於site2分支。對於這種情況還有其他更優雅的解決方案,還是櫻桃採摘正是爲了這個目的?

現在,我真正的「問題」是當我改變主人,然後我想將所有這些改變複製到所有分支。當然,考慮到所有分支都是主人的後代,而我想要在所有網站*分支的變化,我切換到每個分支和合並主人。

這會爲所有分支創建一個非常討厭的歷史。每一輪合併的相當複雜圖形,這使我得出兩個結論:

  1. 分層分支機構只要我看我的步驟,並且沒有做任何愚蠢的可以工作的這種方式,而不是試圖讓任何意義在所有分支機構的歷史圖表中。或..
  2. 必須有一些更好,更合適的方式來做到這一點。

爲了說明我的「問題」,我將給出一個創建這些分支後得到的圖形圖像,添加了很少的分支特定提交,挑選其中的幾個,添加和合並來自主機的一個提交到所有分支,提交或兩個特定的分支,然後再進行一次主合併。

sort of not-so-simple history graph

我不知道,我喜歡簡單,也許我不習慣看到難以遵循這樣一個圖表(這隻會在複雜每以下合併長大,我'我害怕)。

我想我可以一路做櫻桃採摘,並有整潔的歷史圖,但這聽起來也不對,因爲我可能會連續做幾次提交,然後忘了選擇其中一個所有其他分支...

所以...任何想法,經驗,建議,你不介意分享?

更新:我在接受的答案的評論中選擇了一個解決方案。感謝所有貢獻的人!

更新2:即使它不是密切相關的這個問題,recently I stumbled upon this model of branching這似乎是適用於幾乎任何有組織的開發週期,以GIT作爲基本DVCS。這是一個非常好的閱讀。推薦的。

+1

太少時間的答案,但看看'rebase'。 – KingCrunch 2011-05-12 11:39:15

+2

合併可能並不像您想象的那麼糟糕。從根本上說,合併意味着「將另一個分支的所有東西都合併到這個分支中」 - 這聽起來像是你想要做的。你可能想使用'git merge --log'在合併提交消息中包含合併提交的主題列表,然後使用'git log --first-parent'(或'gitk --first-parent ')查看siteX分支上的歷史記錄。 – Cascabel 2011-05-12 12:30:14

回答

4

備選答案:

您可以將分支級別的抽象級別移動到存儲庫級別。用主分支創建一個主庫。爲每個站點克隆這個存儲庫。在主分支上進行更改時,請將這些更改拖入每個站點回購站。這樣你就只需要每個回購一個主分支。


原來的答覆:

當主分支已經改變,你可以變基的其他分支到更新的主分支。假設您有pl_site基於掌握一些承諾和主人發生了變化:

o---o---o---o---o master 
     \ 
      o---o---o---o---o pl_site 

已重訂pl_site後,它看起來像:

o---o---o---o---o master 
        \ 
        o'---o'---o'---o'---o' pl_site 

注意上衍合版本提交pl_site是新的。現在,pl_site包含對主設備所做的更改。

命令:

$ git checkout pl_site 
$ git rebase master 
+0

這隻能讓你到目前爲止。一年之後,這種變化可能行不通,而且爲了達到這個目的,你最終可能會毀掉歷史。 (也就是說,第一次提交超過'master'的pl_site'的'並不一定總是適用於master'的的'任何將來的版本。) – Cascabel 2011-05-12 12:23:12

+0

這並不解決實際問題,'rebase'只是破壞提交歷史等等它看起來很漂亮。 – 2011-05-12 12:28:24

+0

@Dietrich:它的歷史,那相貌醜陋,所以無論你容忍,它被破壞,或者你把它醜陋的(或者你找到一個工具,只是打印它漂亮:d) – KingCrunch 2011-05-12 12:30:24

1

我沒有給你一個很好的答案,因爲你的問題是複雜的,有複雜的解決方案。

選項1:重構

你說的是不同的網站是「基本相同的網站」。因此,將它們移到不同的項目中,並將main_site保存在一個項目中。其他網站將包括main_site作爲子項目。

所以,橫幅......

en_site/ 
en_site/images/banner.jpg 
en_site/master/ 
en_site/master/images/banner.jpg 

您的網站代碼,配置腳本,部署腳本,或任何將確保images/banner.jpg選擇了master/images/banner.jpg。也許當你部署網站master/images首先被複制,然後images被複制,也許你做更復雜的事情。

這可能是很多工作。然而,當你看看歷史,你會得到這樣的事情:

en_site: A -> B -> C -> D 
de_site: E -> F -> G -> H -> I 
main_site: J -> K -> L -> M -> N -> O 

選項2:使用的darcs

在的darcs,你可以從分支移動補丁分支。一些商業VCS也可以做到這一點。所以,你的分支應該是這樣的:

master: patch1 patch2 patch3 patch4 
en_site: patch1 patch2 patch3 patch4 en1 en2 en3 
de_site: patch1 patch2 patch3 patch4 de1 de2 de3 

假設你想將補丁en2德國網站。

de_site: patch1 patch2 patch3 patch4 de1 de2 de3 en2 

Voila。但是,這並不像看起來那麼幹淨。 Darcs愛好者會指出,這個補丁模型與我們的「將補丁移動到另一個分支」的概念模型相匹配,但是,這掩蓋了事實,即您仍然需要測試以確保en2補丁不會破壞所有內容當你把它放在de_site

例如,如果en2將代碼的相同部分更改爲de1會怎麼樣?然後怎樣呢?無論您使用的是什麼VCS,您都必須手動合併。對於每一個這樣的明顯情況,VCS都不會檢測到另一個案例,您必須自己檢查。

我的經驗

當我使用git第一次開始,這似乎是git merge是神奇的。但是,沒有任何VCS技巧會掩蓋事實,即您的網站存在一些非常複雜的相互依賴關係。您可以重構您的站點以消除相互依存關係,或者希望您的VCS歷史不會變得如此複雜以至於無法再理解它。

新枝,新項目,重構事物之間的權衡成庫是一個微妙的權衡。維護大量的補丁集比維護大量使用公共庫的大量項目工作要多得多,重構所需的(大量)工作量可能會很快得到回報。或者它可能不會。

+0

我在十字路口上正確地描述了您所描述的內容。因此,無論我要以某種合理的方式重構並實施這些每個站點的具體內容,以便他們可以相互覆蓋,或者我將選擇不那麼簡單但可維護的基於VCS的解決方案,同時保持代碼完整。感謝您的想法。 – 2011-05-12 12:41:55