1. 程式人生 > >SVN分支/主幹Merge操作小記

SVN分支/主幹Merge操作小記

mis 刪除文件 影響 項目 ssi path 環境 project 選中

一、前言

  說來慚愧,鄙人從事開發多年,使用svn已經好幾個年頭了,但是卻僅限於update、commit、compare之類的操作,最近想到github上學習別人寫的NIO源碼,順便去熟悉git的使用,但是一想到svn,我心裏虛了:用了那麽多年卻對其一知半解,就連最基本的權限分配都沒有做過,更別說進行分支拉取和合並了,何談去get其他技能?做技術的還是要踏實一點,近一年來,我都在對之前未深入的領域進行掃盲,所以,註定svn是繞不過的坎,於是乎開始各種查資料,安裝svn服務端(Virtual SVN)和客戶端(TortoiseSVN),比對網上的博文進行各種嘗試,不能說過程痛苦,但是當你在雲裏霧裏摸索的時候挺難受的吧(順便說下,在學習的時候精力一定要集中!對我而言,順便塞上耳塞聽音樂工作效率是事半功倍,哈哈哈~)~不廢話了,今天這篇博文就講講SVN裏面比較高級的操作:創建分支(branch)、將主幹(trunk)中的代碼合並到分支(branch)、將分支(branch)中的代碼合並到主幹(trunk)中~

二、正文

  說到分支和主幹,我想不少coder也是比較少接觸吧,畢竟很多時候,我們想著的還是如何趕進度~之所以出現分支和主幹,就是希望主幹和分支兩份代碼可以各自進行獨立的管理互不影響,在需要的時候再進行合並。試想這樣一種場景:公司項目已經完成一個階段的開發計劃,這時候拉取一個branch專門用來測試以及BUG修復,而原先trunk上面的代碼還可以繼續往下開發,互不影響,等測試的branch問題修復之後,將這個branch“合並”回trunk。這樣trunk和branch可以在互不幹擾的情況下各自做自己的事兒,最後再進行整合,合並過程中有可能會有沖突,這個並不麻煩,等出現沖突的時候自行百度,我相信你們可以解決的,如果還是暈乎乎,歡迎加群交流~

  接下來我就來說說如何創建分支(branch)、將主幹(trunk)中的代碼合並到分支(branch)、將分支(branch)中的代碼合並到主幹(trunk),首先說明一下筆者當前測試環境:

  1. Virtual SVN 1.9.5(傳送門:https://www.visualsvn.com/server/download/)
  2. TortoiseSVN 1.9.5(傳送門:https://sourceforge.net/projects/tortoisesvn/files/1.9.5/Application/)

   準備工作(以上客戶端服務端自行安裝,除了安裝路徑看自己喜好之外,其他都按照默認設置,點擊“下一步”吧):

  1)創建repository

  打開Virtual SVN,在左側列表中,右鍵Repositories,新建一個repository,名字隨意,格式筆者是選擇FSFS,Repository Structure筆者選擇Single-project repository******,這樣方便後面的描述,為了測試的方便,在選擇“Repository Access Permissions”的時候,選擇所有人SVN的user都有訪問這個repository的權限(user可以在Virtual SVN的左側列表Users節點右鍵,進行新增)

   技術分享

    技術分享

    技術分享

    技術分享

技術分享

  2)Check out trunk目錄到本地

  首先復制剛剛新建的repository下trunk的SVN URL

  技術分享

  在本機隨意一個目錄新建一個空目錄,比如筆者在d盤新建了一個svntrunk的目錄,然後右鍵=>SVN Check out,將trunk的svn地址復制到“URL of repository”那一欄,然後點擊“OK”

  技術分享

  3)在D:\svntrunk目錄下新建一個目錄(名稱設為project),然後在新建的目錄下新增兩個text文件:1.txt(文件內容:111111),2.txt(文件內容:222222),然後右鍵這個project目錄,先Add,然後進行commit

  技術分享

技術分享

  技術分享

  技術分享

  

  4)創建分支(branch)(嘮叨一下,分支是創建在SVN服務器的repository中,而merge是合並在開發者本地)

  右鍵D:\svntrunk\project文件夾,選擇TortoiseSVN->Branch/tag,在彈出的對話框中,To path輸入分支存放在repository的相對目錄,這邊註意:project01不能先創建,不然會報project01已經存在,不能創建分支!在log message中輸入創建分支的日誌,這對後續了解這個分支創建的目的有一定意義。在log message輸入欄下面,還有一個Create copy in the repository from的選項,這個選項的目的是為了讓開發者選擇用哪份源碼作為創建的版本 ,第一個是trunk中最新的版本,第二個用戶可以選擇trunk中指定的版本(通過序號標識),第三個是將工作拷貝作為創建分支的版本

  技術分享

  上步點擊OK之後,創建分支完成,就是這麽簡單,現在請先記住,我們是以trunk中版本序號是2的工程作為創建分支的版本,這個對後續的合並有意義~(這邊順便說下,在一個repository,版本號是一個全局資源,不管是trunk、branch還是tag,他們使用的版本號不會重復,比如現在trunk已經用掉2這個版本號,那麽分支就只能往下一個,用3)

  技術分享

  

  5)分支(branch)中的代碼合並到主幹(trunk)

首先,就像之前將主幹(trunk)Check out到本地一樣,將svn服務器上面的分支(branches)Check out到D盤svnbranches目錄:

  技術分享

  現在假設主幹(trunk)和分支(branche)並行開發,主幹(trunk)project下1.txt的文件內容改為121212,分支(branch)中project1下面增加一個3.txt文件,文件內容為:333333

  右鍵主幹中project文件夾,選擇TortoiseSVN->Merge,這時會彈出一個Merge type讓你選(TortoiseSVN1.9.5這個版本只有兩個選項,網上有些博文有三個選項),Merge type的選擇還是很有講究,並且也是很容易搞錯的,下面會具體來說說:

  技術分享

  我們先來說說“Merge a range of revisions”這個選項:

  我們選中這個選項,然後點擊“Next”,會看到如下界面,因為我們是要將分支(branch)合並到主幹(trunk),所以這邊URL to merge from選項要選擇服務器上面需要合並到主幹(trunk)的分支(branch)地址(註:前面有提過,合並是合並到本地的working copy,所以一般合並之前,最好將本地working copy代碼先更新一遍,有沖突的解決沖突,並且將未提交的代碼提交,以防在合並之後,未提交的代碼丟失),這邊有個Revision range to merge選項,當選擇all revisions進行merge的時候,TortoiseSVN做了怎麽樣的操作呢?其實就是:diff and apply。diff是比較URL to merge from指定的工程最新一個版本和最初的一個版本的差異,假設最新版本是r-last,最初的版本r-first,r-last相對r-first而言,增加了文件a,修改了文件b,那麽在合並的時候,就將“增加文件a,修改文件b”的操作應用在本地的working copy上面去,這就完成了合並;假設選擇的是specific range,那麽用戶可以選擇一個版本範圍,也可以單獨指定一個版本或者不填寫任何值(此時相當於選all revisions),假設用戶指定了版本r1-r3,其中r1新增了文件a,r2新增了文件b,r3刪除了文件c,那麽在合並的時候TortoiseSVN就會將“新增文件a,新增文件b,刪除文件c”應用於本地的 working copy,這樣就完成了合並~

  (ps:這邊還有一個Reverse merge復選框,恢復之前的合並。假設我們剛剛做的merge有問題,需要將本地的working copy恢復成merge之前的,那麽就需要將之前應用於本地working copy的操作全部回退,操作和merge基本一樣,只是最後,需要復選這個Reverse merge復選框)

  技術分享

  上步選擇了Revision range to merge之後,點擊“Next”,進入如下界面,這時我們就可以看到如下界面:

  技術分享

  全部使用默認的選項,然後在點擊Merge之前,可以先點擊Test merge按鈕,測試一下merge之後的效果:

  技術分享

  如上圖所示,分支(branch)版本新增的3.txt文件最終會合並到本次working copy中,最後將本地working copy中的3.txt提交到svn中,這樣就完成了分支到trunk的合並了~

  

  我們再來說說這個“Merge two different trees”,從它自己選項的解釋來看,是將兩個不同的分支(branch)合並到本地working copy中,當然,我們也可以用這個選項將分支(branch)修改的內容合並回主幹(trunk)。選擇Merge two different trees,點擊Next

  技術分享

  上步之後,會出現如下對話框,註意,我們現在是將分支(branch)合並回主幹(trunk),這個時候,我相信很多人想當然的認為Fom處填寫的應該是分支(branch)的URL,而To,應該是主幹(trunk)的URL,因為是從分支(branch)到主幹(trunk)啊,然後事實並非如此!之前在創建分支(branch)這一節,有讓讀者記住拉取分支(branch)時,主幹(trunk)的版本號,當時主幹(trunk)的版本號是2,所以From處的URL應該寫主幹(trunk)的URL,Revision應該選2(其實trunk revision為2的版本,其實也就是branch的第一個版本,所以這邊From可以選擇主幹拉取分支的版本,也可以選取分支最開始的版本),而To處的URL應該選分支的URL,Revision選HEAD Revision,也就是選最新的分支版本。現在就來說說為什麽要這樣填寫:此處進行merge的時候,進行的操作也是diff and apply,將To處URL和revision指定的某個版本,與From處URL和Revision指定的某個版本進行對比,對比是有順序的,這個怎麽理解呢?比如現在To處的為工程project1,From處的為工程project,如果project1相對於project而言,有文件a,沒有文件b,換句話說project1相對於project而言,“新增了a,刪除了b”,那麽此處merge的結果就是會將“新增a,刪除b”的操作應用於本地working copy的工程,那為什麽From處的project不能指定為最新的Revision呢,既HEAD Revision?試想一下,假如主幹(trunk)在拉取了分支(branch)之後,主幹(trunk)和分支(branch)都有在並行開發,那麽必然主幹(trunk)上會有新增的功能,這樣就會有新增的代碼,這些代碼在分支(trunk)上並不存在,在To和From比較過程中,就會出現“刪除xxx”的操作,這在merge過程中會應用在本地working copy中,本來這個“xxx”是主幹新功能的代碼,在將分支合並過來的時候,不應該刪除,所以不能用主幹最新的版本和分支最新的版本做對比,應該是將當時拉取分支的時候的主幹版本和當前最新的分支版本進行對比,應用到本地working copy中才對,所以這邊的From必須選取當時拉取當前分支的主幹版本,不然主幹上面新增的代碼會丟失,之前我對From和To的順序,以及revision的選取也是迷糊了大半天,我希望對讀者而言,我這邊已經說清楚了~如果還有什麽不清楚的歡迎加群交流~

技術分享

  上步之後,點擊Next,進入下面這個頁面,同樣,在最終merge之時,點擊Test merge

  技術分享

  點擊Test merge之後,可以看到最終合並之後的效果

  技術分享

  6)主幹(trunk)中的代碼合並到分支(branch)

  這邊的操作和分支(branch)合並到主幹(類似),需要註意的是,Merge type如果選擇“Merge a range of revisions”,那麽範圍的起始版本應該為拉取分支時的主幹版本,結束版本應該為trunk最新的版本;如果選擇“Merge two different trees”,那麽From必須是選取拉取分支時的主幹的版本,或者分支的第一個版本,To必須是主幹最新的版本

  

  最後總結一下:不管選取哪個Merge type,都能完成主幹到分支、分支到主幹的合並,需要註意的是,在選擇“Merge two fifferent trees”時From和To對應的URL所代表的含義(5)分支(branch)中的代碼合並到主幹(trunk)這一節有講),並且需要了解合並的原理,那麽拉取分支和合並的操作並不是什麽難事。如有什麽疑問,請加群交流~

三、鏈接

1、http://blog.csdn.net/zhuyong0722/article/details/8965095

2、http://blog.csdn.net/wjtxt/article/details/8623262

3、http://www.cnblogs.com/firstdream/p/5632296.html

四、聯系本人

  為方便沒有博客園賬號的讀者交流,特意建立一個企鵝群(純公益,非利益相關),讀者如果有對博文不明之處,歡迎加群交流:261746360,小杜比亞-博客園

SVN分支/主幹Merge操作小記