2011-01-25 39 views
6

我已經贏得了使用Git或Subversion重組/重建現有代碼存儲庫的任務。在這種特殊情況下,資料庫歷史記錄不一定非常重要。在分析情況後,我發現一些問題決定了一個好的佈局。我已經閱讀了很多博客和主題,但我仍然不確定什麼是最佳佈局。如何構建由多個庫和應用程序組成的存儲庫

現有的存儲庫包含一組包含文件,一組相互部分依賴的庫,其中許多庫依賴於一組包含文件。此外,還有兩個應用程序項目依賴於這組庫。此外,還有一組腳本使用其中一個應用程序和一些其他配置信息。我畫一個圖來說明情況:

+---------->include files 
    |    ^
    |    | 
library A -----> library B <----- library C <----- library D 
^^        |    ^
    | |        |    | 
    | +--------------------------------+    | 
    |             | 
application 1  application 2 --------------------+ 
^
    | 
script -----> configuration information 

的目標是讓每個組件可以被儘可能地獨立開發的佈局,有一個版本(對於外部客戶),它包含了一組所有組件都在定義的標籤版本中,以便可以及時回溯併爲特定版本構建軟件。

我想出如下結構:

trunk/ 
    include/ 
    lib/ 
    library A/ 
    library B/ 
    library C/ 
    library D/ 
    app/ 
    application 1/ 
    application 2/ 
tags/ 
    1.0/ 
    include/ 
    lib/ 
     library A/ 
     library B/ 
     library C/ 
     library D/ 
    app/ 
     application 1/ 
     application 2/ 
    1.1/ 
    include/ 
    lib/ 
     library A/ 
     library B/ 
     library C/ 
     library D/ 
    app/ 
     application 1/ 
     application 2/ 
    ... 

每次我創建一個新的版本我只想整個存儲庫複製到一個新的子目錄中的標籤。

此解決方案的問題在於,庫本身沒有單獨的標記目錄,而且我只想擁有由標記的組件組成的版本,並且此解決方案不顯示哪些組件具有哪些標記版本發佈。我曾考慮過使用單獨的存儲庫,然後創建一個主存儲庫,該存儲庫具有一個releases子目錄,其中我使用`svn:externals'和特定的標籤子目錄鏈接所有必需的組件,但不同的庫和包含文件相互依賴,看不出如何將代碼分成不同的實體。

任何想法?

===============問題繼續28-1-2011 ===============

好,我繪製了我如何規劃新佈局的圖表。我們的目標是將 各種依賴關係的標記與一個 存儲庫中的svn:externals方法鏈接起來,例如我將012/中的svn:externals設置爲^/tags/projects/include中的trunk/projects/lib/library2/dependencies /std/1.3。

trunk/ 
    projects/ 
    include/ 
     std/ 
    lib/ 
     library1/ 
     dependencies/ 
      std/ --> tags/projects/include/std/1.2 
     library2/ 
     dependencies/ 
      std/ --> tags/projects/include/std/1.2 
      library1/ --> tags/projects/lib/library1/1.4.3 
     library3/ 
     dependencies/ 
      std/ --> tags/projects/include/std/1.3 
      library1/ --> tags/projects/lib/library1/1.4 
    app/ 
     application1/ 
     dependencies/ 
      library3/ --> tags/projects/lib/library3/1.1 
     application2/ 
     dependencies/ 
      library1/ --> tags/projects/lib/library1/2.1 
     application3/ 
     dependencies/ 
      std/ --> tags/projects/include/std/1.2 
      library2/ --> tags/projects/lib/library2/1.5.2 
    config/ 
     configuration1/ 
     dependencies/ 
      application1/ --> tags/projects/app/application1/2.3 
     configuration2/ 
     dependencies/ 
      application1/ --> tags/projects/app/application1/1.6 
     configuration2/ 
     dependencies/ 
      application2/ --> tags/projects/app/application1/1.6 
tags/ 
    projects/ 
    include/ 
     std/ 
     1.2/ 
     1.3/ 
    lib/ 
     library1/ 
     1.4.3/ 
     1.4/ 
     2.1/ 
     library2/ 
     1.5.2/ 
     library3/ 
     1.1/ 
    app/ 
     application1/ 
     1.6/ 
     2.3/ 
branches/ 
    ... 

剩下的問題:

  • 這是設計可行的,還是你看到任何重大的缺點?
  • 如果我將庫複製到標記目錄會發生什麼?這也會複製 svn:externals屬性。這會導致問題,還是這種行爲需要?
  • 我可以爲所有外部指定顯式修訂,但標籤不應該改變,所以不會改變目錄嗎?
  • 將存儲庫拆分爲開發存儲庫和使用svn:external的存儲庫是一個更好的解決方案嗎?請參閱What's the benefits of "svn:externals"?問題的答案'用例'。
+2

你的問題與Git有什麼關係?你已經展示的結構完全是Subversion特有的。 – ssmir 2011-01-25 18:14:44

+1

繼Google/Wikipedia之後,Git支持真正的標記,問題與標記有關。所以如果可以用Git創建一個比Subversion更好的解決方案,我可能只需切換到Git。我不依賴於Subversion,只是在OSS上。 – hochl 2011-01-25 20:31:19

回答

6

我建議把裏面的分類學轉向。在顛覆,我建議的分類如下:

companyname/ 
    include/ 
    trunk/ 
    tags/ 
    branches/ 
    libraryA/ 
    trunk/ 
    tags/ 
    branches/ 
    libraryB/ 
    trunk/ 
    tags/ 
    branches/ 
    libraryC 
    trunk/ 
    tags/ 
    branches/ 
    libraryD/ 
    trunk/ 
    tags/ 
    branches/ 
    application1 
    trunk/ 
    tags/ 
    branches/ 
    application2 
    trunk/ 
    tags/ 
    branches/ 

在混帳,我建議你應該創建包括LibraryA的,libraryB,應用1,等一個單獨的混帳回購協議......

這種結構將允許您可以在不同部分之間創建任何類型的依賴關係(例如,application1中的分支可能依賴於libraryA項目的不穩定版本,而application1中的HEAD依賴於libraryA項目的穩定版本)。

這種結構也是行之有效的大部分建立像行家,耙,buildr,螞蟻等

您呈現看起來像是爲你的應用程序的部署版本一個很好的結構,但不是一個很好的分類工具版本控制結構。根據經驗,如果您使用類似於我爲版本控制建議的結構,然後使用構建腳本(或構建工具)來創建列出的結構,那麼在打包/部署/運送你的應用程序

UPDATE:爲了詳細說明工作週期會如何走位:

因此,舉例來說,假設我們完成了實現bug修復的應用1(我們稱之爲版本1.0.0)。最新的和最大的變化被檢入到application1/trunk中。此版本的Application1依賴於libraryD v0.5.0。你需要更新application1/trunk/README.txt,注意這個版本依賴於libraryD v0.5.0。也許,更重要的是,應用程序/ trunk中的構建腳本知道如何檢出libraryD/tags/0.5.0。接下來,在application1/tags/1.0.0中創建一個標籤(它只是當前狀態下的一個trunk的副本)。

現在,假設一週過去了,另一位開發人員將libraryD更新到版本1.3.0。您需要增強application1。所以,在application1/trunk中進行更改。然後更新application1/trunk/README.txt以表示您現在依賴於libraryD v1.3.0(同樣,application1 v1.3.0的新構建腳本將檢出libraryD/tags/1.3.0)。將application1/trunk複製到application1/tags/1.1.0。

現在,如果需要,現在您可以隨時恢復到application1/tags/1.0.0(並確信它會從libraryD/tags/0.5.0中提取代碼,application/tags/1.1.0將使用libraryD 1.3版。 0.

在Subversion和git中,標籤都是在給定時間點回溯到一組文件的引用,這意味着標籤不會佔用太多空間,所以我會提前標籤並且經常標籤。 - )

1

一個重要的問題是,如果所有庫和應用程序緊密耦合到單個產品中,或者它們可以獨立生活。 IMO把它們放到一個單獨的git倉庫中是很有意義的,如果所有的庫和應用程序都是一個單一的產品,除了svn之外,你不能只檢出一部分git樹。當庫和應用程序是獨立的,你可以爲每個庫/應用程序創建一個庫,並通過子模塊將它們粘合在一起。

Git子模塊類似於svn extarnals,但它們始終引用目標的特定修訂版,從不只是一個普通的url。所以當你運行git checkout deadbeef時,你總是從創建提交deadbeef的時候開始獲取子模塊狀態,而不管引用的repo的頭是哪個。所以一個git標籤也需要每個子模塊的狀態,這與svn不是一個修訂版固定的url不同。

相關問題