SVN trunk、branch、tag的用法

Subversion有一個很標準的目錄結構,是這樣的。
好比項目是proj,svn地址爲svn://proj/,那麼標準的svn佈局是

svn://proj/|+-trunk+-branches+-tags
這是一個標準的佈局,trunk爲主開發目錄,branches爲分支開發目錄,tags爲tag存檔目錄(不容許修改)。可是具體這幾個目錄應該如何使用,svn並無明確的規範,更多的仍是用戶本身的習慣。

對於這幾個開發目錄,通常的使用方法有兩種。我更多的是從軟件產品的角度出發(好比freebsd),由於互聯網的開發模式是徹底不同的。
第一種方法,使用trunk做爲主要的開發目錄。
通常的,咱們的全部的開發都是基於trunk進行開發,當一個版本/release開發告一段落(開發、測試、文檔、製做安裝程序、打包等)結束後,代碼處於凍結狀態(人爲規定,能夠經過hook來進行管理)。此時應該基於當前凍結的代碼庫,打tag。當下一個版本/階段的開發任務開始,繼續在trunk進行開發。
此時,若是發現了上一個已發行版本(Released Version)有一些bug,或者一些很急迫的功能要求,而正在開發的版本(Developing Version)沒法知足時間要求,這時候就須要在上一個版本上進行修改了。應該基於發行版對應的tag,作相應的分支(branch)進行開發。
例如,剛剛發佈1.0,正在開發2.0,此時要在1.0的基礎上進行bug修正。
按照時間的順序

1.0開發完畢,代碼凍結
基於已經凍結的trunk,爲release1.0打tag
此時的目錄結構爲
svn://proj/
             +trunk/ (freeze)
             +branches/
             +tags/
                     +tag_release_1.0 (copy from trunk)
2.0開始開發,trunk此時爲2.0的開發版
發現1.0有bug,須要修改,基於1.0的tag作branch
此時的目錄結構爲
svn://proj/
             +trunk/ ( dev 2.0 )
             +branches/
                           +dev_1.0_bugfix (copy from tag/release_1.0)
             +tags/
                     +release_1.0 (copy from trunk)
在1.0 bugfix branch進行1.0 bugfix開發,在trunk進行2.0開發
在1.0 bugfix 完成以後,基於dev_1.0_bugfix的branch作release等
根據須要選擇性的把dev_1.0_bugfix這個分支merge回trunk(何時進行這步操做,要根據具體狀況)
這是一種很標準的開發模式,不少的公司都是採用這種模式進行開發的。trunk永遠是開發的主要目錄。

第二種方法,在每個release的branch中進行各自的開發,trunk只作發佈使用。
這種開發模式當中,trunk是不承擔具體開發任務的,一個版本/階段的開發任務在開始的時候,根據已經release的版本作新的開發分支,而且基於這個分支進行開發。仍是舉上面的例子,這裏面的時序關係是。

1.0開發,作dev1.0的branch
此時的目錄結構
svn://proj/
             +trunk/ (不擔負開發任務 )
             +branches/
                           +dev_1.0 (copy from trunk)
             +tags/
1.0開發完成,merge dev1.0到trunk
此時的目錄結構
svn://proj/
             +trunk/ (merge from branch dev_1.0)
             +branches/
                           +dev_1.0 (開發任務結束,freeze)
             +tags/
根據trunk作1.0的tag
此時的目錄結構
svn://proj/
             +trunk/ (merge from branch dev_1.0)
             +branches/
                           +dev_1.0 (開發任務結束,freeze)
             +tags/
                     +tag_release_1.0 (copy from trunk)
1.0開發,作dev2.0分支
此時的目錄結構
svn://proj/
             +trunk/
             +branches/
                           +dev_1.0 (開發任務結束,freeze)
                           +dev_2.0 (進行2.0開發)
             +tags/
                     +tag_release_1.0 (copy from trunk)
1.0有bug,直接在dev1.0的分支上修復svn

==============================================================佈局

主幹(trunk)、分支(branch )、標記(tag)測試

在SVN中Branch/tag在一個功能選項中,在使用中也每每產生混淆。編碼

 
在實現上,branch和tag,對於svn都是使用copy實現的,因此他們在默認的權限上和通常的目錄沒有區別。至於什麼時候用tag,什麼時候用branch,徹底由人主觀的根據規範和須要來選擇,而不是強制的(好比cvs)。

通常狀況下,spa

trunk:是用來作主方向開發的,一個新模塊的開發,這個時候就放在trunk,當模塊開發完成後,須要修改,就用branch。
branch:是用來作並行開發的,這裏的並行是指和trunk進行比較。
tag:是用來作一個milestone的,無論是否是發佈版本,但都是一個可用的版本。這裏,應該是隻讀的。更多的是一個顯示用的,給人一個可讀的標記。

好比,3.0開發完成,這個時候要作一個tag,tag_release_3_0,而後基於這個tag作發佈,好比安裝程序等。trunk進入 3.1的開發,可是3.0發現了bug,那麼就須要基於tag_release_3_0作一個分支(branch),branch_bugfix_3_0,基於這個branch進行bug修改,等到bugfix結束,作一個tag,tag_release_3_0_1,而後,根據須要決定 branch_bugfix_3_0是否併入主幹(trunk)。

對於svn還要注意的一點,就是它是全局版本號,其實這個就是一個tag的標記,因此咱們常常能夠看到,什麼什麼release,基於xxx項目的 2xxxx版本。就是這個意思了。可是,它還明確的給出一個tag的概念,就是由於這個更加的可讀,畢竟記住tag_release_1_0要比記住一個很大的版本號容易的多。

branches:分枝
當多我的合做,可能有這樣的狀況出現:John忽然有個想法,跟原先的設計不太一致,多是功能的添加或者日誌格式的改進等等,總而言之,這個想法可能須要花一段時間來完成,而這個過程當中,John的一些操做可能會影響Sally的工做,John從現有的狀態單獨出一個project的話,又不能及時獲得 Sally對已有代碼作的修正,並且獨立出來的話,John的嘗試成功時,跟原來的合併也存在困難。這時最好的實踐方法是使用branches。 John創建一個本身的branch,而後在裏面實驗,必要的時候從Sally的trunk裏取得更新,或者將本身的階段成果聚集到trunk中。
建立分支的命令:設計

(svn copy SourceURL/trunk DestinationURL/branchName -m "Creating a private branch of xxxx/trunk." )

trunk:主幹
主幹,通常來講就是開發的主要呆的地方,


tag::標記
在通過了一段時間的開發後,項目到達了一個里程碑階段,你可能想記錄這一階段的代碼的狀態,那麼你就須要給代碼打上標籤。
建立標記的命令:
(svn cp file:///svnroot/mojavescripts/trunk file:///svnroot/mojavescripts/tags/mirrorutils_rel_0_0_1-m "taged mirrorutils_rel_0_0_1")

另有一說,無所謂誰對誰錯。

trunk:表示開發時版本存放的目錄,即在開發階段的代碼都提交到該目錄上。

branches:表示發佈的版本存放的目錄,即項目上線時發佈的穩定版本存放在該目錄中。

tags:表示標籤存放的目錄。

在這須要說明下分三個目錄的緣由,若是項目分爲一期、二期、三期等,那麼一期上線時的穩定版本就應該在一期完成時將代碼copy到branches上,這樣二期開發的代碼就對一期的代碼沒有影響,如新增的模塊就不會部署到生產環境上。而branches上的穩定的版本就是發佈到生產環境上的代碼,若是用戶使用的過程當中發現有bug,則只要在branches上修改該bug,修改完bug後再編譯branches上最新的代碼發佈到生產環境便可。版本控制

 

 

tags的做用是將在branches上修改的bug的代碼合併到trunk上時建立個版本標識,之後branches上修改的bug代碼再合併到trunk上時就從tags的version到branches最新的version合併到trunk,以保證前期修改的bug代碼不會再合併。

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

一直以來用svn只是看成cvs,也歷來沒有仔細看過文檔,直到今天用到,纔去翻看svn book文檔,慚愧

需求一:
有一個客戶想對產品作定製,可是咱們並不想修改原有的svn中trunk的代碼。
方法:
用svn創建一個新的branches,從這個branche作爲一個新的起點來開發
svn copy svn://server/trunk svn://server/branches/ep -m "init ep"

Tip:

若是你的svn中之前沒有branches這個的目錄,只有trunk這個,你能夠用
svn mkdir branches
新建個目錄

需求二:
產品開發已經基本完成,而且經過很嚴格的測%日誌

 

================================================================視頻

——簡單的對比server

  SVN的工做機制在某種程度上就像一顆正在生長的樹:

  • 一顆有樹幹和許多分支的樹
  • 分支從樹幹生長出來,而且細的分支從相對較粗的樹幹中長出
  • 一棵樹能夠只有樹幹沒有分支(可是這種狀況不會持續好久,隨着樹的成長,確定會有分支啦,^^)
  • 一顆沒有樹幹可是有不少分支的樹看起來更像是地板上的一捆樹枝
  • 若是樹幹患病了,最終分支也會受到影響,而後整棵樹就會死亡
  • 若是分支患病了,你能夠剪掉它,而後其餘分支還會生長出來的哦!
  • 若是分支生長太快了,對於樹幹它可能會很是沉重,最後整棵樹會垮塌掉
  • 當你感受你的樹、樹幹或者是分支看起來很漂亮的時候,你能夠給它照張相,這樣就就能夠記得它在那時是多麼的贊。

——Trunk

  Trunk是放置穩定代碼的主要環境,就好像一個汽車工廠,負責將成品的汽車零件組裝在一塊兒。

  如下內容將告訴你如何使用SVN trunk:

  • 除非你必須處理一些容易且能迅速解決的BUG,或者你必須添加一些無關邏輯的文件(好比媒體文件:圖像,視頻,CSS等等),不然永遠不要在trunk直接作開發
  • 不要由於特殊的需求而去對先前的版本作太大的改變,如何相關的狀況都意味着須要創建一個branch(以下所述)
  • 不要提交一些可能破壞trunk的內容,例如從branch合併
  • 若是你在某些時候偶然間破壞了trunk,bring some cake the next day (」with great responsibilities come… huge cakes」)

——Branches

  一個branch就是從一個SVN倉庫中的子樹所做的一份普通拷貝。一般狀況它的工做相似與UNIX系統上的符號連接,可是你一旦在一個SVN branch裏修改了一些文件,而且這些被修改的文件從拷貝過來的源文件獨立發展,就不能這麼認爲了。當一個branch完成了,而且認爲它足夠穩定的時候,它必須合併回它原來的拷貝的地方,也就是說:若是原來是從trunk中拷貝的,就應該回到trunk去,或者合併回它原來拷貝的父級branch。

  如下內容將告訴你如何使用SVN branches:

  • 若是你須要修改你的應用程序,或者爲它開發一個新的特性,請從trunk中建立一個新的branch,而後基於這個新的分支進行開發
  • 除非是由於必須從一個branch中建立一個新的子branch,不然新的branch必須從trunk建立
  • 當你建立了一個新branch,你應當當即切換過去。若是你沒有這麼作,那你爲何要在最初的地方建立這個分支呢?

——Tags

  從表面上看,SVN branches和SVN tags沒有什麼差異,可是從概念上來講,它們有許多差異。其實一個SVN tags就是上文所述的「爲這棵樹照張相」:一個trunk或者一個branch修訂版的命名快照。

  如下內容將告訴你如何使用SVN tags:

  • 做爲一個開發者,永遠不要切換至、取出,或者向一個SVN tag提交任何內容:一個tag比如某種「照片」,並非實實在在的東西,tags只可讀,不可寫。
  • 在特殊或者須要特別注意的環境中,如:生產環境(production)、?(staging)、測試環境(testing)等等,只能從一個修復過的(fixed)tag中checkout和update,永遠不要commit至一個tag。
  • 對於上述說起到的環境,能夠建立以下的tags:「production」,「staging」,「testing」等等。你也能夠根據軟件版本、項目的成熟程度來命名tag:「1.0.3」,「stable」,「latest」等等。
  • 當trunk已經穩定,而且能夠對外發布,也要相應地從新建立tags,而後再更新相關的環境(production, staging, etc)

——工做流樣例

  假設你必須添加了一個特性至一個項目,且這個項目是受版本控制的,你差很少須要完成以下幾個步驟:

  1. 使用SVN checkout或者SVN switch從這個項目的trunk得到一個新的工做拷貝(branch)
  2. 使用SVN切換至新的branch
  3. 完成新特性的開發(固然,要作足夠的測試,包括在開始編碼前)
  4. 一旦這個特性完成而且穩定(已提交),並通過你的同事們確認,切換至trunk
  5. 合併你的分支至你的工做拷貝(trunk),而且解決一系列的衝突
  6. 從新檢查合併後的代碼
  7. 若是可能的話,麻煩你的同事對你所編寫、更改的代碼進行一次複查(review)
  8. 提交合並後的工做拷貝至trunk
  9. 若是某些部署須要特殊的環境(生成環境等等),請更新相關的tag至你剛剛提交到trunk的修訂版本
  10. 使用SVN update部署至相關環境
Thing to Name Name Style Examples1 Examples2
Release branch RB-rel RB-1.0 RB-1.0.1a
Releases REL-rel REL-1.0 REL-1.0.1a
Bug fix branches BUG-track BUG-3035 BUG-10871
Pre-bug fix PRE-track PRE-3035 PRE-10871
Post-bug fix POST-track POST-3035 POST-10871
相關文章
相關標籤/搜索