2011年2月5日 星期六

版本控制隨筆 (1)

由於工作上的需要,我在從事開發工作後便開始接觸了版本控制系統。Subversion 是我第一個接觸的版本控制系統。那時,對於版本控制系統的體會大概就是:哇!這實在非常方便。我可把程式寫一個段落,然後將它上傳到一個伺服器裡。即使,我不小心殺掉了電腦裡的資料,只要重建好開發環境,再將專案由伺服器上抓回來就能繼續工作。這是我對版本控制系統最先感受到的好處。事實上,也是對版本控制系統的錯誤理解。要做到同樣的功能,用 email 或 ftp 上傳檔案,其實是一樣的事情。有太多技術能做到把檔案便利地保存至遠端,所以我向自己提出這樣的疑問:是哪些特質使得版本控制系統,不同於哪些將檔案方便上傳至伺服器呢?這個問題的答案,同時也是拒絕使用分散式版本控制工具的常見迷思之所在。

將檔案保存至中央的伺服器,只是版本控制系統實作的一種型式。通常我們稱這一類版本控制系統為集中式的版本控制系統,如 Subversion 或 CVS 都是屬於這一類。它們都需要依賴一個中央的伺服器來處理版本控制的行為。版本控制系統的存在,並不只是為了讓使用者方便地將檔案上傳至伺服器,上傳至伺服器只遷就於版本控制系統的實作模型的需要產生的副作用。這個行為,我們稱為提交(Commit)。提交是指您決定好將目前對於檔案(有時包含目錄)的變更,記錄在版本控制系統,每一筆記錄就是一個修訂版本(Revision)。對版本控制系統來說,它必需準備一個資料庫來存放這些記錄,這個特殊的資料庫被稱作檔案庫(Repository)。

修訂版本是個相當好的想法,因為它不同於一個時間點。當有人提出 qrtt1 你前天改的那個版本好像有問題?這時就得傷腦筋,前天的那時候的那一個改變產生了問題呢?或是其實不是前天,而是發生在昨天呢?這時版本控制系統能發揮的作用就是在哪一個修訂版出了問題。作為開發者能將修訂版本回溯到指定的修訂版本。這時版本控制系統發揮了作用,讓我們能將專案回復到特定的狀態,而針對確認問題的重演(Reproduce)行為才得以精確實履行。對於專案活動來說,適當地使用版本控制系統。您得先掌握專案議題與修訂版本的關係。新的功能(Feature)實作的可能會產生一連串的修訂版本。當功能達到一個里程碑時,我們也能用修訂版本記錄這個有意義的狀態。要檢驗該功能是否完備,就是要檢查該修訂版本(或該本版本之後)的專案狀態。因此,我們習慣將議題追蹤系統與版本控制系統做若干的結合。至少,我們能在議題完成的評論欄位附註修訂版號。而臭蟲回報(Bug Report)時,也是相類的作法。當 QA 回報什麼功能有問題時,在最新的狀態下若能重演問題,那就能附註在最新的修訂版本下能從演此問題。若該功能能對於至過去的議題,那就能找問題發生的修訂版本,這能輔助面對問題時,找出發生的根源與時間點。修訂版本,持有的資訊不僅是專案的變更記錄,還包含變更者與變更的時間。這讓問題的發現與觀念調整的對象皆同時獲得。

儘管在我描述中的修訂版本是如此便利,但某些版本控制系統的修訂版本並不適合這樣使用。以 CVS 來說,它的修訂版本是每一個檔案擁有自己的修訂版本。這在使用上會產生許多困擾,因為我們必需找出某個特定的時間點,各別檔案對應的修訂版本將它們各別回復成我們設想的狀態。若您想要擁有一個代表整體改變的修訂版本,在 CVS 下的替代方案就是使用標籤(Tag)。對 CVS 的使用者來說,標籤就是替一群檔案目前修訂版本取別名的動作。但這在使用上算是額外的動作,開發者有可能會遺忘下標籤的作動,喪失在適當的時機建立修訂版本的機會。而 Subversion 與其他較新的版本控制系統就有變更集合(Changeset) 的概念,它將同時被提交的檔案視為一個修訂版本(有些版本控制系統的設計者,甚至以較嚴謹的交易機制來實作,使得提交的具大 atomic 的性質)。因此,這樣的修訂版本就自然地產生出來,您不需要額外進行下標籤的動作。

回過頭來,先前提過版本控制系統允許您透過提交(Commit)產生修訂版本(Revision)。您可以這樣想:每一個修訂版本都是一份檔案庫記錄的快照(Snapshot),就像照相一般,將那個時刻的狀態保存下來。我們能利用版本控制系統提取(Checkout)的功能,取出最新的資料庫記錄,或著特定的修訂版本。在某些情況,版本控制系統亦提供利用標籤產生修訂版本別名的功能。別名就如同朋友之間的暱稱,指稱暱稱,如同指稱本人。因此,我們向版本控制系統提取記錄時,可以使用修訂版本代號,也可以使用標籤。除此之外,稍後將介紹的開發支線(Branch)也能作為提取的目標。

檔案庫(Repository)、修訂版本(Revision)、提取(Checkout)、提交(Commit)與標籤(Tag),這些概念與動作即為版本控制系統使上用的基本觀念,同時為版本控制系統提供的基礎建設。然而,這些基本的功能是無法滿足軟體開發的實際需要。對開發團隊來說,最舒適的狀態是我們知道我們永遠有能夠穩定的工作版本能使用。而對應到採用版本控制系統的情境來說,我們有個穩定的版本,它的標籤是 Release-0.1 (實際上對應的修訂版號可能是 Rev 1981)。無論什麼時候,我們都能提供客戶最穩定的版本。同時,我們的工作伙伴也能進行新功能的開發。儘管正在開發的功能,還沒告一段落,我們都希望版本控制系統能輔助所有的開發活動能被記錄起來。

沒有留言:

張貼留言