Introduction

本書將會告訴你如何使用版本控制來增進軟件開發過程中的有效性。
 
版本控制,有時也叫源碼控制。項目的三大支柱,它首當其中。我們把版本控制的應用視爲所有項目的必修課。
 
無論對於團隊或是個人,版本控制都有著許多優點。
  • 它爲團隊提供了一個項目全局範圍內的 undo 按鈕;沒有什麽是不可改變的,錯誤可以輕易的回滾。想像一下,你正在使用這世上最棒的字處理機,它有著所有你可以想像得到的功能,除了一個:因爲某些原因,他們忘了加入 Delete 鍵。想想你將要如何謹慎而緩慢的進行輸入,特別是在一個超長的文檔接近完成的時候。一個錯誤,你就不得不重新開始。同樣的情況下,使用了版本控制,我們可以回到一小時、一天、或是一星期前,這樣就可以解放你的團隊,讓他們快速、自信的進行工作,因爲他們有了一個修正錯誤的方法。
  •  
  • 它允許多個開發人員工作在一個受控方式下的相同的代碼上。當有人覆寫了團隊成員編輯的代碼時,改動也不再會丟失了。
  •  
  • 版本控制系統隨時都保留著一份變更的記錄。即便你遇到一些“令人驚訝的代碼”,也可以很容易的找出是誰、什麽時候以及爲什麽(可能的話)進行的改動。
  •  
  • 版本控制系統允許你在進行主線開發工作時對軟件的多個發佈版本同時進行支援。有了版本控制系統,發佈前的 code freeze 期間,團隊的工作也無需停止。
  •  
  • 版本控制是一臺項目全局範圍內的時光機,它讓你可以回到某一天,並清楚了解當天項目的狀況。這對研究工作來說是很有用的,但更重要的是,它可以重建較早前向客戶發佈的有問題的版本。(譯注:這對找出之前版本的問題所在極爲有用)
本書主要從項目的角度來闡述版本控制。我們並不是簡單的列出一個版本控制系統內可用的命令,而是從一個成功項目所需的工作出發,看看版本控制系統能給予我們什麽樣的幫助。
 
在實踐中版本控制是怎樣工作的呢?我們從一個小故事開始吧...
 
 

1.1 版本控制的應用

Fred 進入辦公室,急於繼續新 Orinoco 圖書訂購系統的工作。(爲什麽是 Orinoco?因爲 Fred 的公司使用河流的名稱爲所有內部項目命名。)第一杯咖啡過後,Fred 從中央版本控制系統 check out 出項目源碼的最新版本更新他本地的副本。日誌中列出了被更新的文件,他留意到 Wilma 改寫了基礎 Orders 類的代碼。Fred 開始擔心這個改動是不是會影響到他的工作,但今天 Wilma 去客戶那安裝最新發佈的版本了,所以不能直接問她。於是 Fred 求助於版本控制系統,讓它顯示有關 Orders 類改動的記錄。Wilma 的注釋並沒有打消他的顧慮:
 
    * 爲 Order 類加入新的交付選項字段
 
爲了搞清楚發生了什麽事,Fred 回到版本控制系統看了看源文件中實際的改動。他留意到 Wilma 加入了幾個實例變量,但它們卻被設爲默認值而且似乎沒有被改變。這可能會是個問題,不過這無關痛癢,所以他繼續工作。
 
Fred 爲系統加入了一個新的類以及幾個測試類,創建它們的同時 Fred 也爲它們在版本控制系統中加入了相同的文件名,而文件本身並不會被加入,直至 Fred 提交他的改動爲止,現在加入它們的名稱可以讓 Fred 在稍後不至於忘記。
 
幾個小時後,Fred 完成了一些新功能的首部分並通過了其自身的單元測試,它將不會影響系統的其它部分,所以 Fred 決定將它提交到版本控制系統,好讓團隊的其它成員可以看到。這幾年中,Fred 發現經常的 check in/out 要比把它放幾天合理得多:如果你需要擔心的只是幾個文件而不是一週內整個團隊做出的所有改動,那麽解決偶然出現的衝突將會輕而易舉。
 

爲什麽你永遠都不該接聽電話

正當 Fred 准備開始下一輪的編碼時,他的電話響了。是 Wilma,從客戶那邊打來的。她安裝的那個版本似乎有個 bug:打印出來的發票並沒把銷售稅計算在付運金額上。客戶非常生氣,需要馬上修正。
 

除非你使用版本控制...

Fred 和 Wilma 再一次檢查了問題版本的名稱,然後從版本控制系統 check out 出這個版本的所有文件。Fred 將它放到自己機器的一個臨時目錄下,因爲他打算在完成工作後將它刪除。現在在他的電腦裏就有了兩份系統源碼的副本:主版本和已對客戶發佈的版本。因爲要進行修正,所以 Fred 讓版本控制系統爲他的源碼加上了標簽。(修正這個 bug 後他會加入另一個標記。這些標記標識著開發中的重點。通過使用統一命名的標記,無論在他完成修改的前後,其它組員都可以清楚的知道稍後他們應當關注的改動是什麽。)
 
爲了將這個問題分離出來,Fred 先寫了一個測試用例。這當然足夠了,似乎從來就沒有人檢查過與付運相關的銷售稅的計算,因爲他的測試用例馬上顯示出了問題所在。(Fred 爲此做了筆記並在這次的迭代回顧會議上提了出來;這類問題對客戶應當是透明的。)Fred 爲所有應征稅的類都加入了付運的代碼,編譯、檢查,他的測試用例已經通過了。作爲一次快速的完整性測試,他重新運行了測試套件然後把修正後的代碼提交到了中央版本控制系統。最後,Fred 爲發佈版本加入了一個標識表明 bug 已經被修複,然後向負責這部分的 QA 發送了一份筆記。有了他的標識,他們就可以做出一張包含了這個修正的交付磁盤。然後 Fred 回電給 Wilma 告訴她修正後的版本已經在 QA 的手上應該很快就會送到她那的了。
 
處理完這讓人稍稍分心的事,Fred 在他的機器上刪除了發佈版本的代碼:改動已經安全的提交回中央服務器,代碼並沒有被搞亂。之後他開始想:相同的 bug 是不是也存在於當前的開發版本中?最快的檢驗方法就是將他剛才爲發佈版本編寫的測試用例加入到開發版本的測試套件中。他讓版本控制系統將發佈版本裏具體的改動與開發版本中相應的文件合併。合併過程根據發佈文件中的變更爲開發版本中的文件作出了同樣的改動。當他運行測試用例時,新的測試失敗了:bug 再次出現。然後他將發佈版本中的修正應用到開發版本中。(他的機器上並不需要有發佈版本的代碼,所有的改動都從中央版本控制系統獲得。)一旦測試都通過了,他會將這次的改動提交回版本控制系統,這樣下次就少了個煩人的 bug。
 
危機過去了,Fred 繼續自己今天的工作。整個下午他都在愉快的編寫著測試用例和代碼直到收工。在他工作的同時,團隊的其它成員也在進行改動,於是 Fred 通過版本控制系統將其它的改動應用到他本地的代碼中。他運行最後一次的測試,然後提交,爲下一個工作日作好准備。
 

明天

很不幸,這天出了些狀況。前晚 Fred 的中央暖氣系統終於還是掛了。Fred 住在 Minnesota,現在是二月,麻煩大了。他打回公司說他今天可能都要等維修人員的到來。
 
然而,這並不意味著他得停止工作。Fred 使用安全鏈接通過公網將開發版本的代碼 check out 到他的筆記本電腦上。因爲在前晚他回家的時候已經提交過了,因此所有最新的代碼都在那。他在家裏著裹毛毯坐在火爐旁繼續工作。最後他將筆記本電腦上所做的改動提交,這樣下一個工作日他就可以從這裏繼續了。生活是美好的。(除了那張維修的帳單。)
 

故事書項目

版本控制在 Fred 和 Wilma 項目上的正確應用並不十分起眼,但卻給予了他們控制權以及幫助他們相互通信,甚至是當 Wilma 在很遠的地方時。Fred 可以查出代碼中的改動然後分別爲他們程序的多個發佈版本作出修正。他們的版本控制系統支持離線工作,所以 Fred 可以不受地點的約束:他可以在他的暖氣系統掛掉的情況下在家裏進行工作。因爲他們在適當的位置上有版本控制(他們知道應該如何使用它),Fred 和 Wilma 處理過很多項目的緊急事件,他們的鎮定常常影響著我們對意外的響應。
 
版本控制讓 Fred 和 Wilma 即使面對多變的真實世界依然不失控制權以及靈活性。這也是本書的內容所在。
 
 

1.2 說明

下一章,What Is Version Control?,將會介紹版本控制系統的概念及術語。有許多版本控制系統可供我們選擇,本書使用的是自由的 CVS;它可能是目前應用最廣泛的版本控制系統。
 
第三章,Getting Started with CVS,是 CVS 的入門指南。其餘章節則是一套 CVS 在項目中的應用技巧。這部分分爲六章,每章都包含了許多的技巧:
  • CVS 中不同的連接方法。
  •  
  • 常用 CVS 命令。
  •  
  • 使用標記和分支來處理發佈版本和實驗版本的代碼。
  •  
  • 創建一個項目。
  •  
  • 創建子模塊。
  • 處理第三方代碼。
我們在結尾的附錄中對所有的技巧作了總結,另外還列出了其它的資源以及參考書籍。