CVS版本管理

CVS版本管理之長劍出鞘

我參與的項目release好一段時間了,這期間經歷了市場血與火的洗禮...。做應用軟件的就是這樣,你一定會碰到不同用戶的不同需求,你需要爲其定製開發。好,當有A省的用戶有特殊的需求的時候,我們就用CVS爲其建立一個新的project。同理,當有B省用戶有特殊的需求的時候,我們還是採用同樣的辦法。我們一開始沒有覺得這樣哪裏不好,爲不同的用戶建立不同的project,很清晰,維護起來還挺方便。就像《後天》裏的情節哪樣,你總是要對你不正確的做法付出慘痛的代價。我們很快發現了我們的做法的致命傷,當我們需要修改一個bug,或者是升級程序,加入通用的功能的時候,我們需要手工同步很多版本。god,大量的重複勞動!我清楚的聽到我鄰座那個可愛的女孩的抱怨:真麻煩,要同步這麼多版本。

有的時候,我覺得自己很幸運^_^。當有一個問題困擾着我的時候,我準備上一個常去的論壇向guru請教的時候,發現大家正在那裏熱火朝天的討論着這個問題。這次也差不多,一天晚上和一個以前的同事聊了一些關於版本管理的問題。那個同事現在在一家外企工作,據稱他們的版本管理很規範,有很專業的專門人員來做這件事情。他告訴我,應該可以採用CVS的分支功能來解決這個問題。雖然我當時雲裏霧裏,不太明白,他也不是做版本管理的,但是,重要的是這個idea。我是一個聽人勸的人,馬上從一個同事那裏揩來《CVS-開源軟件開發技術》那本書。仔細的研究了一下分支的功能。嘖嘖,這就是我想要的,哈哈,在屋裏跳了一會小天鵝。嗯,程序員總是這樣大喜大悲的!

把我的輕騎兵音箱調到很大聲,聽着《癡心絕對》。我喜歡這樣寫文章^_^。好吧,讓我們看看什麼是CVS的分支。

我們把一個項目的一個主要開發過程稱作開發主線。當某一個特殊事件發生的時候,例如,有一個用戶有特殊的需求,於是就從這個開發主線裏分離出來一個叉,以滿足用戶特殊的需求,那麼這個叉有它自己的發展方向,這就是分支,就像是一個大樹在春暖花開的時候,長出來的新枝。

           ---------分支
          /
         /
        /
  ------●----------------------------開發主線


上面這個點,代表開發主線的最新版本,那麼這個時候可以從開發主線建立分支來進行定製開發。接下來,開發主線和分支就可以有各種的發展方向。而且,如果可以的話,分支的代碼可以重新合併到開發主線中。開發主線的代碼也可以更新到分支代碼中。

假設在我們的home目錄下的proj目錄就是我們的工程。下面具體看一下,如何建立分支:

1、先在開發主線上創建一個標籤,就是上圖中那個點。這樣做是爲了以後可能有使主幹重新回到分支創建時的狀態的需求。在你的工程目錄的top level下執行cvs tag Root-of-Version_2.5.0.0。

2、創建分支:cvs tag -b ln_version_branch(-b選項就是創建分支)。

3、接下來,你可以在工程目錄的top level下直接執行cvs update -r ln_version_branch轉到分支上進行工作。也可以通過cvs co -r ln_version_branch -d ln_proj proj命令新checkout一份分支的本地拷貝。-d選項是創建本地目錄名字。這裏建議用第二種用法,因爲在一個本地拷貝下通過命令來回在主線和分支轉換,容易產生混淆,你也可能忘記這麼去做。

4、這樣分支的開發和主線的開發就可以分離開。如果需要的話,可以把分支上的代碼合併到開發主線上,當然在合併的過程中可能需要解決一些衝突。cvs update -j ln_version_branch,通過這樣的命令把分支代碼合併到主線上。當然我們這裏的例子是針對用戶特殊需求產生的分支,一般不會把分支合併到開發主線中。但是,對於bug修改等產生的分支,就會有需求把分支合併到主線上。這裏有一點要強調的是,當開發主線的程序員合併分支的代碼的時候,需要互相溝通。在開發主線程序員成功合併分支代碼後,在主線代碼上要設立一個點(cvs tag)來標誌這次合併;在分支代碼上開發的程序員,在合併之後,也要建立一個點來標誌這次合併,例如,cvs tag ln_version_1。這樣做的好處是當下次在進行代碼合併的時候,在開發主線上的程序員可以通過命令cvs update -j ln_version_1 -j ln_version_branch,這裏ln_version_branch代表分支的末梢,因此該命令不是重新合併整個分支代碼,而是合併自從合併點ln_version_1到現在修改的代碼,這樣可以防止重新合併整個分支而帶來的衝突。

5、對於我們這裏針對用戶特殊需求產生的分支,可能更多需要的是把開發主線上的代碼更新到分支上。cvs update -j HEAD,這裏HEAD代表了主幹的末梢,也就是這個命令合併了主線在創建該分支伊始到目前爲止,所有的主線上修改的代碼。這裏還是需要分支開發人員和主線開發人員溝通。在分支上也需要設立一個點來標誌這次合併,這樣如果主線需要合併分支代碼的時候,可以根據這個點進行新的合併,而不是合併整個分支。主線開發人員也需要設置點來標誌這次合併,例如,cvs tage merged-ln_version_1 ,這樣下次分支在合併主線代碼的時候可以cvs update -j merged-ln_version_1 -j HEAD ,這樣防止了分支重複合併主線上的代碼,而只是合併最新的修改。

上面我們可以看到,一個主要規則是,當進行代碼合併的時候,一定要注意溝通,合理的設置合併點。並且,合併點的名字也應該望文生義^_^。各個線上的合併工作也最好由一個人來做。如果合併點設置不當,那麼分支帶來的好處可能就會打折扣。並且如果管理的不好,整個項目可能會很亂,產生意大利麪條式的分支^_^。

CVS的工作模式:

CVS的基本工作模式如下:

                  CVS服務器(代碼文檔庫)                       /     |       /    (版 本 同 步)   /      |        /                  開發者1  開發者2   開發者3

CVS在服務器端維護代碼文檔庫,不同的開發者在本地機器上建立對應代碼樹,並利用CVS保持本地代碼文檔同代碼文檔庫的一致。當由於多個開發者對文件的同時修改造成本地與庫中的代碼文件衝突時,CVS報告並協助解決衝突代碼的合併問題。普通開發者(非管理員)對CVS的使用流程如下所示:

    Check out(獲取)  -------------------- Merge(合併)          |         |                            ^          v         v            Conflict(衝突)  |    Modify(修改)-> Update(更新)   ----------------      ^              |      |              | No Conflict(無衝突)      |              v    Update(更新) <- Commit(提交)                     |                     v            Export(導出)

check out命令只需在開始建立本地代碼樹時使用一次,其後更新本地代碼則使用update命令。update命令比較服務器和本地代碼庫的區別,並把本地代碼樹中過時的文件自動更新。當完成對代碼的修改之後,在提交代碼之前同樣需要使用update命令,以獲取他人並行修改的的代碼。如果出現衝突(即對同一文件同時進行了修改),CVS將在本地代碼中把兩者都保留並標記出來,要求開發者處理衝突。在衝突不存在或已解決的情況下,使用commit命令將服務器代碼更新爲本地代碼。CVS要求爲更改提供註釋,並自動爲更新的文件處理版本編號。當軟件需要正式發佈時,使用export命令導出不包含CVS設置信息的源代碼樹。

CVS的管理員還使用包括init, import, admin等命令對服務器和代碼庫進行配置和設置。

發佈了24 篇原創文章 · 獲贊 3 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章