[轉載]項目svn版本控制中的分支策略

[原創]項目svn版本控制中的分支策略
by AKara 2010-06-07 @ http://blog.csdn.net/akara @ akarachen(at)gmail.com @weibo.com/akaras


  結合項目運營的一些體會,淺談一下項目中經常用到的分支策略。


  從一個很舊的PDF <<Essential CVS>> 上發現了一些篇章,回頭一讀發現
多年前精簡的原則闡述放到現在來說,仍有非常好的指導意義,基本涵蓋我
打算要總結的內容了,乾脆翻譯一遍它。雖然用的是svn,但是應該和cvs本質
上是相同的理念~
  
---------------------------------------------------------------------
(翻譯倉促,如需轉載請先聯繫:http://blog.csdn.net/akara / [email protected])

4.4 Branching Strategies
  本章將講述分支策略中的基本原則以及兩種主要的分支原則。
並給予一些關於 何時/爲何 你需要在一個項目中開闢分支的解答。

4.4.1 Branching Philosophies
  關於分支的經驗法則是:保持開發的主線位於trunk(主幹)上;而其他的一切,
branch(分支)。問題在於如何界定哪些是開發的主線。trunk應該只包含穩定
的代碼還是也可容忍不穩定的代碼?是否在每個release被測試前都應該分支?
新功能應該在trunk上開發還是在一個branch上開發?

  上面這些疑問都源於我們對'開發的主線'有兩種不同的定義。這兩種定義引出
了兩種截然不同的分支原則,術語上稱basically stable和basically unstable。

4.4.1.1 Basically stable
  顧名思義這個分支原則主導思想是trunk只包含穩定的隨時可發佈的代碼。
branches則用於開發新功能/修正bug/發佈前的QA控制/重構/實驗性質功能試點。
  
  該原則下最嚴格的遵行方式爲:任何未經嚴格QA控制的代碼都不能merge回trunk。
這樣便能保證任何時刻都可以從trunk上分出一個release candidate(rc),
它只需要通過少量的QA控制流程便能進入正式發佈。

  不那麼嚴格的遵行方式則允許通過開發者的unit-testing的代碼merge回trunk。
這種稍微寬鬆的方式則需要通過全套的QA控制監督才能進入正式發佈流程。

  Basically stable原則下有一些優點:
  * 任何時刻可以分出一個release。並配以簡單QA控制就加以發佈。
  * 因爲trunk只包含穩定的代碼,並且變動的節奏很慢;
    所以你可以在branch上作大量的實驗性改動,而不用擔心merge回trunk時
    會和別人的工作摻雜在一起而導致bug。
    
  而這個原則下最大的缺點是:merge通常由QA測試員來進行而不是理解代碼語義
的編寫者來進行。另一個缺點是:在從一個branch往trunk merge完成後,trunk
上的改動相對於這個branch被分出去的那個版本來說,可能是巨大的。當然這兩個
問題都可以通過使開發者週期性地merge回trunk而得到一定程度上的減輕;或者
遵行更爲寬鬆的merge要求。

4.4.1.2 Basically unstable
  Basically unstable原則下,要求trunk包含最新的代碼,不管它的穩定性如何;
而用於release candidate的版本則應該開闢一個分支來交付。

  該原則下最嚴格的遵行方式爲:所有開發都在trunk上進行,只有rc,
bugfix branch,release等性質的事件纔會開闢branch。

  稍爲寬鬆的遵行方式爲則允許使用branch來進行實驗性編碼,重構,以及其他
特殊用途的代碼開發。而往trunk merge則通常由相應branch的負責者來完成。
  
  Basically unstable原則的優點是merge是個不常發生的事情,而且是個相對
容易完成的事情———因爲是由熟悉branch代碼的負責者來完成merge。

  而它的缺點顯然是trunk包含了不穩定的代碼,可能是實驗性功能,甚至連
編譯都不能通過的代碼。經常進行tagging可以減少這個缺點帶來的影響,
所以每次對每次實驗功能和重構等進行tag操作是個好習慣。更寬鬆的的遵行
方式是將那些bug傾向極大的代碼從trunk上branch出去,爲隨時從trunk準備
一個release提供更好的環境。

4.4.2 Branch Styles
  CVS包含創建和使用branch的一些方法,但是它不強迫使用者必須使用某種
技巧來使用。本章介紹幾種使用branch的風格。
  
  本章中的"long branch"術語指的是正在使用的branch或者經過多次merge
回trunk的已經廢棄的branch。而'short branch'術語是指那些只merge一次
回trunk便廢棄的branch。

  當然,CVS中的'廢棄'並不等於不存在;CVS允許任意時刻又重新開始使用任何
一個branch。結束或廢棄一個branch只是簡單地告訴所有開發者:不要再使用
它了。

4.4.2.1 Long branch, merging to branch
  從trunk上往的一個正在開發的branch中經常merge內容的做法對於某些情形
非常有用:trunk不希望受到branch的改動影響,但是branch希望接收trunk上
的有用的改進部分。鏡像站點就是這種情形。圖 4-6 描述了這個做法:
  
                       Branch ______________________
                             /  ↑merge ↑merge ↑merge
              Trunk ——————————————————————>
  
                圖 4-6 從trunk上往branch多次merge內容

4.4.2.2 Long branch, merging to trunk
  從正在開發的branch往trunk中經常merge內容的做法對於如下情形非常有用:
branch不希望受到trunk上改動的影響,但是trunk希望融合branch上的改進。
在一個branch正在處於測試期或正處於發佈前期時;這個做法會有很好的效果。
處於測試中的項目可以採取本做法,將branch上已經測試的修改merge回trunk中。
圖 4-7描述了這個做法:

                       Branch ______________________
                             /  ↓merge ↓merge ↓merge
              Trunk ——————————————————————>
  
                圖 4-7 從branch上往trunk多次merge內容

4.4.2.3 Long branch, merging both trunk and branch
  Long branch和trunk之間也可用互相merge的做法來保證雙方的改動都同時
雙方得到融合。如果開發者在branch上進行着不穩定的編碼工作,那可以在
每個里程碑完成時往trunk中merge,而branch也可以隨時準備接受trunk上的
改動同步。當你一步步地往一些成熟的代碼添加新功能的時候,這個方法可以
很好地進行版本管理。 圖 4-8 描述了這個做法:

                       Branch ______________________
                             /  ↑merge ↓merge ↑merge
              Trunk ——————————————————————>
  
                圖 4-8 trunk和branch互相merge

4.4.2.4 Short branches
  爲一個簡單功能修改而開闢的獨立branch我們叫它short branch。如果你希望
增加一個獨立功能 / 編寫實驗性代碼 / 準備發佈版本,那這就是很理想的做法。

  顯然可以用系列的short branches來模擬一個long branch在branch和trunk
間相互merge的情況。通過這個方法,就避免了先從long branch中merge改動
回trunk,然後又要從trunk往long branch中merge更改的麻煩——取而代之的是
你只需從short branch中往trunk merge,然後再從trunk開闢一個新的short branch
繼續如此循環,直至達到目標開發量。這種方法很適合在trunk和branch都將有
重大的變動的情形。圖 4-9 描述了這個做法:

                       Branch _____   Branch_____  Branch_____
                             /     ↓merge  /     ↓merge /     ↓merge
              Trunk ———————————————————————>
  
                圖 4-9 short branches 
  
4.4.2.5 Nested branches
  CVS允許從branch上開闢branch。子branch將視父branch爲trunk。上面討論過
的trunk和branch之間的原則可以一樣地繼續應用。嵌套branches在將CVS用作
配置管理系統的時候非常有用。同時需要注意,減少嵌套的複雜度總能減少混淆。
  
  如果你正在一個branch寫一個新功能集合,而又需要在部分功能交付測試時繼續
你的開發,你便應該在這個branch之上再開闢一個新的branch用來交付測試。
見圖 4-10 描述:
                   Branch2.3.2.2.2___2.3.2.2.2.1___2.3.2.2.2___
                                 /
            Branch 2.3.2___2.3.2.1___2.3.2.2___2.3.2.3___2.3.2.4___
                       /                         /
                      /                           /___2.3.2.3.2.1__2.3.2.3.2.2__
                     /
  Trunk ———2.2—————2.3—————2.4——————2.5——————>
  
                圖 4-10 Nested branches 

4.4.3 Branch Polices
  有一些一貫的原則可以幫助你利用分支來加強項目中的版本管理。脫離這些原則,
可能會讓你在一團糟的分支關係中迷失方向。
  擁有和遵守這些原則同時也幫助你將merge變得更加簡單易操作。減低merge的成本
需要branch和trunk上的開發者進行足夠的交流。
  讓這些原則在你的項目和團隊中成爲規章吧。下面是我和同事都覺得有用的
一些原則:
  * 對項目有總體的(版本管理)設計。
  * 開闢每個branch前確定它的目標;並儘量減少項目中有效的branch。
  * 儘量降低branch方案的複雜度。CVS允許嵌套分支,但嵌套分支這種複雜情況
    很少爲項目帶來好處:)
  * 使用一致的branch命名規則來表達分支的用途。
  * 注意branch和trunk的差別同步;好的設計和交流會減少這種問題發生的可能性。
    一個例子是:當一位開發者改變了某函數的參數個數(更糟糕的是,參數的順序);
    但其他開發者仍未得到通知,而且沒有merge,仍在用舊的參數方式來調用函數。
  * 儘量避免在CVS中提交二進制文件,以便CVS進行自動的文件merge操作。
  * 經常merge。顯然,改動越少,merge越簡單。
  * 標記好每個merge點的信息,以便避免對同一個改動重複merge。
  * 在trunk上的每個branch點/merge前/merge後 做好標記信息;方便隨時取回
    某個trunk狀態下的信息。
  * 使用一致的branch標記信息規則。
  
(翻譯倉促,如需轉載請先聯繫:http://blog.csdn.net/akara / [email protected]


---------------------------------------------------------------------

  說回項目中的分支策略。
  假設每次運營維護期大概一週。下面以周爲最短的分支週期。
  我們採取的是 Basically unstable 原則,一般的最新代碼在trunk上開發。
  每次對外發布則開闢rc branch提交QC。然後該branch進入爲期一週的buf fix mode。
  用時一週左右的的改動一般用short branch的形式進行。改動完後一次性往回merge。
  long branch則只用於超過兩週的功能開發。每次merge back操作由branch負責人進行。

  每次rc branch通過QC full tested 後將直接當作release;
  freeze後的二進制檔將自動提交到freeze svn倉庫作爲一個可回滾的發佈版本,
  並由SA作爲最新發布的根據。

  希望有更多的項目運營經驗的朋友交流討論。

原文地址:http://blog.csdn.net/akara/article/details/5662624

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章