基於SVN的項目管理——集中與分散


我們在此處不討論 GIT 比 SVN 好多少,也不討論 Maven 和 Gradle 哪個好用,基於現有的開發環境,大多數公司還是采用 SVN + Maven 來進行項目管理——因為這已經滿足了大多數的代碼管理需求,並且對於一個成熟的公司來講,項目管理工具的改變可能需要很大的成本和決心,基於 GIT 的項目管理將會在以后詳細介紹。

做程序開發和項目管理的老銀棍們肯定知道,基於 SVN 的項目開發管理有兩種方式:集中式開發和分散式開發,對應正常的語言描述來講,集中式開發對應的是基於trunk進行開發,而分散式開發對應的就是基於branches進行開發。兩者並沒有絕對的好壞之分,具體采用哪種方式,完全憑個人喜好、項目架構和公司規定進行選擇。

集中式開發——基於Trunk的開發

基於主干的開發方式可能是比較主流的開發方式,三個目錄的主要定義如下:

trunk:開發工程(非穩定)

tag:我們認為穩定的發布包

branches:BUG、需求變更分支

用語言描述一下開發步驟:在trunk中新建一個項目,此時版本號是1.0.0-SNAPSHOT,分配權限給所有的開發人員,所有開發人員功能開發完畢之后提交代碼到trunk,測試基於trunk進行測試,此時trunk處於鎖定狀態——不允許再在trunk上進行新功能的開發,測試完畢之后打tag,至此1.0.0-RELEASE版本正式發布,trunk中的版本號變為1.1.0-SNAPSHOT,解鎖Trunk,所有開發人員開始開發1.1.0-SNAPSHOT,此時如果發生未測出來的BUG和需求變動,基於1.0.0-RELEASE的tag打分支1.0.0-PATCH,所有相關開發人員對1.0.0-PATCH進行維護開發,同時主干的1.1.0-SNAPSHOT也在同步進行。

這里很多人會問,如何將1.0.0-PATCH中的代碼合並到1.1.0-SNAPSHOT中?這里用一個場景來具體描述

程序員小張負責用戶注冊模塊的開發,在整個項目1.0.0-RELEASE發布之后,1.1.0-SNAPSHOT中小張需要對注冊模塊進行一個升級,此時(注意,代碼沒有正式開始編寫),在線上運行的1.0.0-RELEASE版本發現了一個隱秘的BUG(可能是代碼BUG,也可能是業務BUG),小張需要先為1.0.0-RELEASE這個tag打出一個分支1.0.0-PATCH-01對這個BUG進行修復,修復完畢之后,將1.0.0-PATCH-01合並到主干中,生成版本1.0.1-SNAPSHOT,然后發布到Tag中,此時Tags中包含1.0.0-RELEASE和1.0.1-RELEASE兩個tag,之后,進行新版本1.1.0-SNAPSHOT的開發——這是最好的結果。

但是事實並非如人所願,我們最常遇到的情況是1.1.0-SNAPSHOT已經開發了一段時間,此時發現了1.0.0-RELASE中的這個隱藏BUG,需要緊急修復,我們這里同樣用一個場景來具體描述。

程序員小張負責用戶注冊模塊的開發,在整個項目1.0.0-RELEASE發布之后,1.1.0-SNAPSHOT中小張需要對注冊模塊進行一個升級,此時(注意,代碼已經正式開始編寫),在線上運行的1.0.0-RELEASE版本發現了一個隱秘的BUG(可能是代碼BUG,也可能是業務BUG),小張需要先為1.0.0-RELEASE這個tag打出一個分支1.0.0-PATCH-01對這個BUG進行修復,修復完畢之后,將1.0.0-PATCH-01單獨上線接下來的故事就比較復雜了,小張需要將1.0.0-PATCH-01中的代碼手動的與正在開發的1.1.0-SNAPSHOT進行一個合並——這是常見但是異常的結果

為什么說第二個場景屬於常見但是異常,這非常考驗整個PMO管理——為什么會出現緊急BUG?為什么需要緊急上線?這會造成兩個最直接的麻煩:

1. 線上版本不是RELEASE版本的,而是一個分支PATCH。

2. 將PATCH中的代碼合並到正在開發的代碼中會異常痛苦。

如果遇到這樣的情況,首先不能慌張,盡可能的先將線上的BUG解決掉,再來考慮如何在新版本中合並代碼的問題,這樣肯定會造成1.1.0的延期發布以及1.0.1的缺失,嚴重的可能還需要重新審視——但是你避免不了,不過責任是比較清楚的。

 

當然為了能夠盡可能的避免這種情況出現,一般建議新版本上線后的一段時間內(比如一個禮拜)開發人員先暫停開發做一個休整,做做項目總結、補充一些文檔之類的工作,之后再進行1.1.0的迭代,這樣做不僅能夠完美收尾,還能減少情景2出現的概率,對公司、開發人員以及項目管理來講都是有利的。

 

分散式開發——基於Branches的開發

分散式開發是基於分支branches進行開發,也是我個人比較喜歡的一種方式,其三個目錄的定義如下:

trunk:穩定的主干

tag:我們認為穩定的發布包

branches:開發切片

與集中式開發不同的在於,我們branches中存在的是各個開發人員所負責的切片,而主干中則一直是穩定的SNAPSHOT版本——這其實是符合邏輯的,SNAPSHOT代表的意義是預覽而不是“破爛”,至少能夠正常的運行起來才能算的上是預覽版,而集中式開發的主干雖然標注的是SNAPSHOT預覽版,實際上其實是一個“破爛”——正常情況下你是運行不起來的,開發環境總是存在各種各樣的不確定性。

用語言描述一下開發步驟:在主干trunk中新建一個項目,然后copy to branches,分別建立milestone、sp1、sp2...spN,每一個切片對應一個開發或前端或白盒測試,當大家各自開發完畢之后,提交代碼,項目經理將sp1、sp2等切片合並到milestone中,這里注意了,不是合並到trunk中,而是一個分支的名字叫milestone——里程碑,專門用來合並各種代碼,milestone的代碼進行合並之后,部署到測試環境讓測試組介入測試——完畢之后合並到trunk,然后在trunk上進行發布,在tag中歸檔並上線,trunk中的版本號升級到下一版本,然后所有開發切片重新切片。

上面的描述如果感到拗口的話,可以看這個場景:

項目經理建了一個項目,版本號是1.0.0-SNAPSHOT,程序員小王從項目經理那里領到一個任務是開發訂單查詢中心這個模塊,他的切片是1.0.0-SNAPSHOT-SP1,開發完畢之后提交了代碼,項目經理合並代碼到milestone上,然后小王開始開發其他的代碼,項目經理陸續從小張、小李那邊收到SP2、SP3的代碼之后,覺得可以發布一版了,叫上測試對milestone進行測試,通過之后合並到主干打tag上線,此時線上版本號是1.0.0-RELEASE,主干上的版本號是 1.1.0-SNAPSHOT,此時項目經理重新切片,所有人的代碼從1.0.0-SNAPSHOT-SPn轉換到1.1.0-SNAPSHOT-SPn進行開發,milestone同樣變成1.1.0-SNAPSHOT,循環往復……

同樣存在集中式開發的問題——老版本出現BUG怎么辦?我們這里同樣模擬一個場景。

1.0.0-SNAPSHOT通過了測試並且已經打tag上線了,線上版本是1.0.0-RELEASE,trunk上的版本號是1.1.0-SNAPSHOT,milestone上的版本也是1.1.0-SNAPSHOT,所有的開發都已經認領了各自的1.1.0-SNAPSHOT的SP進行下一版的開發,此時1.0.0-RELEASE發生了一個隱藏的BUG需要緊急修復並上線,項目經理找到BUG負責人小王,讓他對他所負責的1.0.0-SNAPSHOT-SPn進行fix,修補完畢之后依次合並milestone、測試、打tag上線,此時線上版本是1.1.0-RELEASE,主干版本變成1.1.1-SNAPSHOT,milestone同樣為1.1.1-SNAPSHOT。

到此,我們產生了一個疑問:因為小王的BUG導致主干版本比開發的SP版本高了一個版本,是不是會有沖突呢?

其實是沒有沖突的,SP的版本號其實是弱化了的——實際上我根本不關心SP的版本號是否正確,當發生不正確的情況出現,由各個切片的開發人員自己通過Merge里程碑Milestone的代碼解決。

總結一下分散式開發引申出來的幾個概念:

SP:開發切片。

MILESTONE:里程碑,對應的是測試環境

TRUNK:主干,對應的是預發布環境

TAG:歸檔,對應的是線上環境

分散式開發重點解決的是保證測試環境的相對穩定、預發布環境的絕對穩定以及線上環境的絕對穩定問題,並且我們試想一下:是不是能夠輕松做到持續交付了呢?

總結

集中式開發適合一些小型項目的開發,例如微服務、小組件。

分散式開發適合快速迭代——對於未知的需求貼合的更好。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM