目前,我正在從傳統的版本控制系統轉移到我的小組項目,並將其移至mercurial。作爲我正在移動的代碼類型的一個例子,我有一個25+項目的Visual Studio解決方案,其中包含幾個獨立的應用程序區域,這些應用程序區域都依賴於通用代碼。回顧Stack Overflow,我發現的最接近的問題是this one,但它僅僅提到了版本控制。我正在尋找進一步的建議,關於使用Mercurial來管理這些依賴關係的具體實現技術。在Mercurial中組織具有共享依賴項目的項目的好方法是什麼?
依賴關係的簡化視圖如下所示。 (這是爲了說明和示例僅;實際依賴關係是顯著更復雜,但是在本質上相似的。)
Common Lib 1
/ | \
---- | -----
/ | \ \
App 1 Common Lib 2 \ App 2
/ | \ \
------- | ------ |
/ | \|
App 3 App 4 App 5
通用庫模塊將被共享的代碼 - 這將是一個DLL或SO或一些其它庫將在所有應用程序之間同時使用 - 無論是在編譯時還是運行時。否則應用程序可以獨立運行。
我有幾個目標,與建立我的善變庫:
- 給每個顯著應用程序或組件組自己的倉庫。
- 使每個存儲庫自成一體。
- 使項目自成總計。
- 一次構建整個代碼庫很容易。 (最終,所有這些程序和庫最終都會放在一個安裝程序中。)
- 保持簡單。
另一個問題是我有一個服務器設置,我爲這些項目中的每一個都有單獨的存儲庫。
我看到一些將這些項目鋪設的方法。
1.創建一個包含所有內容的「Shell」存儲庫。
這將使用基於URL的subrepos(例如,在.hgsub,我會做這樣的事情App1 = https://my.server/repo/app1
)擺出來,它看起來像下面這樣:
+---------------------------+
| Main Repository |
| | +---------------------+ |
| +-| Build | |
| | +---------------------+ |
| | +---------------------+ |
| +-| Common Lib 1 | |
| | +---------------------+ |
| | +---------------------+ |
| +-| Common Lib 2 | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 1 | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 2 | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 3 | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 4 | |
| | +---------------------+ |
| | +---------------------+ |
| +-| App 5 | |
| +---------------------+ |
+---------------------------+
在每個主文件夾shell存儲庫將包含一個子項目,每個項目區域一個。依賴關係是相對的:例如,由於應用程序4需要公共庫2,它將簡單地使用相對路徑來引用該公共庫。這種方法的
優點:
- 每個庫一次且僅一次拉下來。
- Mercurial的subreos將確保自動在所有項目中使用相同版本的庫,因爲項目中只存在該子報告的一個版本。
- 很容易找到每個資源。這種方法的
缺點:
- 我不能在一個應用程序獨立工作。例如,如果我在App 2上工作,並且需要更改公共庫,則所有其他應用都必須立即進行這些更改。
- 如果我自己拉一個應用程序回購,我必須弄清楚(或知道)如果我想要構建它,還需要手動獲取其他哪些依賴回購。
- 依賴關係並沒有很強的分離 - 因爲很容易獲得所有功能,所以很容易在任何地方插入新功能。
2.有依賴subrepos完全包含。
在這種方法中,每個應用程序都有自己的存儲庫(與以前一樣),但是這次也包含子存儲庫:一個用於其自己的源,另一個用於每個從屬子庫。然後整個資源庫將包含這些項目資源庫中的每一個,並知道如何構建整個解決方案。這將如下所示:
+-----------------------------------------------------------------------+
| Main Repository |
| +--------------------+ +--------------------+ +--------------------+ |
| | Build | | Common Lib 1 | | Common Lib 2 | |
| +--------------------+ | | +--------------+ | | | +--------------+ | |
| | +-| Lib 1 Source | | | +-| Common Lib 1 | | |
| | +--------------+ | | | +--------------+ | |
| | | | | +--------------+ | |
| | | | +-| Lib 2 Source | | |
| | | | +--------------+ | |
| +--------------------+ +--------------------+ |
| +--------------------+ +--------------------+ +---------------------+ |
| | App 1 | | App 2 | | App 3 | |
| | | +--------------+ | | | +--------------+ | | | +--------------+ | |
| | +-| Common Lib 1 | | | +-| Common Lib 1 | | | +-| Common Lib 2 | | |
| | | +--------------+ | | | +--------------+ | | | +--------------+ | |
| | | +--------------+ | | | +--------------+ | | | +--------------+ | |
| | +-| App 1 Source | | | +-| App 2 Source | | | +-| App 3 Source | | |
| | +--------------+ | | +--------------+ | | +--------------+ | |
| +--------------------+ +--------------------+ +---------------------+ |
| +--------------------+ +--------------------+ |
| | App 4 | | App 5 | |
| | | +--------------+ | | | +--------------+ | |
| | +-| Common Lib 2 | | | +-| Common Lib 1 | | |
| | | +--------------+ | | | +--------------+ | |
| | | +--------------+ | | | +--------------+ | |
| | +-| App 4 Source | | | +-| Common Lib 2 | | |
| | +--------------+ | | | +--------------+ | |
| +--------------------+ + | +--------------+ | |
| | +-| App 5 Source | | |
| | +--------------+ | |
| +--------------------+ |
+-----------------------------------------------------------------------+
優點:
- 每個應用程序都可以單獨建造,相互獨立的。
- 庫的相關版本可以按每個應用程序進行跟蹤,而不是全局跟蹤。它需要在項目中插入子報表以添加新的依賴關係。
缺點:
- 在做最終版本,每個應用程序可能會使用不同版本的共享庫。 (可能需要編寫工具來同步常用的lib子目錄。)
- 如果我想構建整個源代碼,我最終會多次下拉共享庫。在Common Lib 1的情況下,我必須把它拉八(!)次。
3.不要包含依賴關係作爲subrepos - 將它們作爲構建的一部分引入。
這種方法看起來非常像方法1,只是通用庫只會作爲構建的一部分被提取。每個應用程序都會知道它需要什麼回購,並將它們放在公共位置。
優點:
- 每個應用程序都可以通過自身建設。
- 通用庫只需要拉一次。
缺點:
- 我們不得不跟蹤當前使用的每個應用程序庫的版本。這複製了subrepo功能。
- 我們不得不建立一個基礎架構來支持這個,這意味着更多的東西進入構建腳本。啊。
4.還有什麼?
有沒有處理它的另一種方法?更好的方法?你嘗試和成功的方式有哪些,你嘗試過但討厭的方式?我目前傾向於1,但是應用程序獨立性的缺乏在它應該能夠真正困擾我的時候。有沒有辦法得到方法2的良好分離而沒有大量的重複代碼拉和依賴維護的噩夢,而不必編寫腳本來處理它(如在選項3中)?
最近在開發人員郵件列表中有關於此主題的討論:http://news.gmane.org/find-root.php?message_id=%3c1302811240.12395.36.camel%40calx%3e – Rudi 2011-05-17 07:41:38
您使用了什麼工具用來創建這些ASCII圖? – 2011-05-17 19:11:19
@caveman:油滑編輯。一個非常時髦的文本編輯器。在該編輯器中右鍵單擊選擇對於移動您喜歡它們的文本列非常有用。 :) – 2011-05-17 21:08:42