2009-10-28 169 views
25

我在SVN中有多個項目。這些項目中的每一個都位於自己的中繼線中,並且分支用於發佈。SVN和幾個項目之間共享的代碼

而且每個項目都有一個共享代碼。問題是處理代碼的最佳方式是什麼。

讓我舉幾種情況以及與之相關的問題

一)放入單獨的樹幹(或庫共享代碼)和使用svn:外部。

在這種情況下,如果我們支鏈的一些項目,會出現兩個問題:

  • 其在主幹由共享代碼的任何修改將被傳播到分支,因爲SVN:外部將搭載更改
  • 在這種情況下,如果我們需要回溯並準確構建用於發佈的代碼,我們很難獲得準確的代碼,因爲snv:external會再次獲取最新的共享副本代碼,而不是項目受到破壞時的代碼。

據我所知有一個解決辦法。只要我們分支,我們可以修改svn:external來獲取共享代碼的精確修改。但是,又有兩個缺陷:

  • 您需要記住每次分支時都要這樣做。 (我討厭這樣的事情,這很容易忘記)。
  • 如果您需要爲分支/發佈項目執行修補程序,則無法修改共享代碼。

b)另一種解決方案是在項目分支時分支共享代碼,並將外部指向共享代碼的分支副本。

  • 再次,問題之一是手動步驟,這很容易忘記
  • 的另一個問題是合併的問題。當您嘗試將項目中的更改合併到主幹時,SVN將跳過外部。因此,開發人員需要記住手動合併共享代碼。

我是否缺少任何東西?有沒有合理的方法來處理這個問題?

+0

您是否找到任何解決方案? – 2017-02-28 05:07:00

回答

13

我個人保留一個單獨的存儲庫,然後使用[http://svnbook.red-bean.com/en/1.0/ch07s03.html svn:externals]屬性。

當您運行svn更新時,SVN Externals允許您鏈接到其他存儲庫(甚至是您不運行的存儲庫,例如smarty subversion repo),您的項目和外部存儲庫都將被更新。

與SVN的外部也可以鏈接到特定版本使用somethign像http://path-to-project.com/svn/thing -r1234的版本,並且你需要保持靜態

最佳實踐恕我直言,是始終指定某個版本爲您做出然後更新版本號的其他東西更改共享庫,以便您可以跟蹤爲什麼更新此數據。當您標記或分支主項目時,它也能保持一切健全。

+0

+1提示提及外部特定版本 – 2009-10-28 17:31:19

+2

這確實是一種很好的做法!或者,只要有可能,指向svn中其他倉庫的標籤:外部鏈接(這應該保證不變性,並且使用哪個版本更容易解釋)。 – RedGlyph 2009-10-28 18:30:41

3

你有兩個正確的答案,有兩套缺點。
這裏就是我會建議

把你的共享代碼到另一個倉庫, 標籤與發行版本 代碼在後備箱目錄中創建一個svn的外部指向你的標籤。

當你改變你的庫,重新編輯它,並更新你的中繼應用程序。 當你分支時,你的分支仍然會指向你的庫的正確標籤版本。

或者嘗試構建一個單獨版本的庫,並將該庫作爲jar或lib/so引用。

+0

聽起來像一個非常好的方法:-) – RedGlyph 2009-10-28 18:37:56

0

我對處理共享代碼(特別是Java和.NET或C/C++庫)的建議是使用兩套存儲庫:一套用於源代碼,另一套用於版本化已發佈圖像。當您對「通用」項目進行更改時,將源代碼更改提交到源代碼樹,然後構建它,然後通過在發佈樹上將它們作爲新版本進行發佈來發布二進制文件。然後使用'common'項目的項目使用svn:externals屬性來引入已發佈的二進制文件。沒有修改共享代碼的本地圖像的誘惑。如果有人想修改「通用」代碼,那麼他們通過該項目的正常開發實踐來實現這一點。

有關更多詳細信息,請參閱此answer到類似的問題。

+0

它有點濫用版本工具,我們傾向於在我們的團隊中愁眉苦臉,但我承認,這很方便。最好是將二進制文件存儲在共享的目錄結構(包括版本)中,只要可以從版本化的源重新創建它們(如果需要調試等等)。將二進制文件存儲在存儲庫中的主要問題是服務器不必要的附加費用。 – RedGlyph 2009-10-28 18:35:37

+0

我也保留了源代碼版本(當然)。在與分佈式開發團隊合作時,使用存儲庫比共享文件系統要好 - 您只需提供顛覆訪問(通過http/https),而不必通過VPN執行CIFS。 – 2009-10-29 13:28:14

2

我們使用一個單一的存儲庫的結構是這樣的:

/trunk/project1 
/trunk/classlibrary (shared code) 
/trunk/project2 

在C#(這可能不是你所選擇的語言),PROJECT1和項目2包括對classlibrary參考。當我們構建(這裏是編譯後的.NET模型的一大優點)時,找到正在構建的項目和class_library之間的任何不一致。這些不一致在提交更改之前已解決。使用基於服務器的構建工具(我們使用CruiseControl.NET),我們可以同時構建所有項目,這將告訴我們任何問題。

除非你的project1和project2需要引用一個特定版本的classlibrary(我們避免,試圖讓project1和project2總是使用class_library的最新版本),這個工作非常順利。

我傾向於避免爲相關應用程序製作單獨的存儲庫。由於上述示例中的class_library將所有這些內容聯繫在一起,因此在項目級別將其分開的真正原因在於它是共享代碼,因此在將它們維護在不同的版本中幾乎沒有優勢或邏輯。共享代碼的生產應用程序出於某種原因這樣做 - 他們應該使用相同版本的共享代碼,這意味着它們應該是同一個源代碼控制分支的一部分。

+1

我真的不喜歡這種結構。一切都融合在一起,變得太複雜了。兩個項目都會立即收到對類庫的更改,這意味着它變得脆弱並且不可擴展。你沒有機會管理你的圖書館,因爲它是自己的實體。 基本上,如果您將project1和project2作爲單獨的產品發佈,那麼這種佈局會帶來很多麻煩。 – 2009-10-29 07:46:56

+0

我猜這裏有不同的觀點。我更喜歡這樣做,因爲它讓我們避免了多個版本的類庫,如果庫中的類的接口被修改,可能會引入不兼容或應用程序之間的不一致。 此外,這將取決於你的意思是「在現場」。在這個例子中,這兩個項目是同一個項目的一個管理站點和一個公共站點 - 它們是獨立的Web應用程序項目,但有很好的理由非常緊密。 – 2009-10-29 15:34:43

3

我們使用類似於CWT的系統:共享代碼本身就是單獨的項目,並且因此獨立存在於存儲庫(或單獨的存儲庫)中。在使用外部項目的項目(上游項目)中,我們包含共享/下游項目的編譯/打包二進制文件。

這樣上游項目就不會被下游項目的意外變化所扼殺。

我們已經編寫了一些腳本來在必要時自動更新這些二進制文件的較新版本的主要上游項目(否則這是一個手動過程,將軟件包複製到適當的項目中,但這並不是什麼大事) 。

我們目前在這個madnes^W方法中看到的缺點是,正在進行活動開發的下游項目(例如,在新庫的早期階段)需要看起來像過多數量的更新到上游項目。測試上游項目可能需要更新共享庫,編譯,上游複製二進制文件,以及編譯/部署/無論上游項目。然而,一旦圖書館最初的瘋狂開發變得緩慢,圖書館變得有些穩定,這個「問題」就會消失。

與CWT,上游項目不能修改任何有意義的方式共享碼。下游變更必須明確在該項目內進行,並在必要時向上遊傳播。

+0

這正是我們現在正在計劃的,具有相同的理由。 – 2009-10-29 07:32:47

+0

我同意supermagic的方法。考慮共享庫而不是共享代碼文件/項目。將共享庫的已編譯二進制文件添加到項目中。這種方法與將外部標籤包含在標籤中具有相同的效果,但是由於管理外部資源而導致的維護困難並不重要。 我遇到的一些問題是創建一個帶外部標籤的樹幹和一個樹幹和分支指向相同的外部。在我看來,外部的風險超過了他們的利益。 – mcdon 2010-09-03 18:39:32

+1

只要您只需要二進制文件,這種方式就可以正常工作,但如果您在共享庫中的某個共享庫中未來運行了一個錯誤,則會停止搜索包含在標記或分支中的庫版本。 – 2010-09-22 16:43:16

0

這是一個從你的列表中缺少的答案是:

三)始終指向的外部的共享代碼的特定版本。

這工作得非常好:

  1. 您可以隨時拆掉你的項目的特定版本,並確保構建。
  2. 分支和標記是項目路徑上的一項操作。
  3. 可以爲1個項目更新共享代碼,但第二個項目在它準備好之前不會接收它們。
  4. 當第二個項目確實發現了這些變化時,您會看到一條事件記錄在您的箱子中,表明它已被拾取,爲什麼。
  5. 您有機會發布具有特定項目特徵的庫的特定版本。這可以讓你出氣孔,如果一個項目是不是準備好了一個API的變化,但需要一定的缺陷修補等

如果需要的話,圖書館可以在單獨的工作拷貝來查看與修改你的旁邊主要項目。如果項目被臨時更改爲從磁盤上的工作副本中提取代碼,那麼如果需要,您仍然可以並行處理庫和項目。

相關問題