在前一回中,我簡單介紹了版本控制系統的觀念還有典型的操作,而在這一回中,我們就來看看這些操作,是如何落實到現實的開發生活中。

版本控制系統需涵蓋的檔案類型
首先,究竟是什麼樣的檔案應該被放到版本控制系統中。

當然,理論上,所有專案中的產出,無論是中間產物或是最終要提交成為產品一部份的,都可以被放到版本控制系統中,以利之後運用版本控制系統的功能。

但是,這並不意謂著你應該將所有的檔案都放到版本控制系統裡,事實上,你應該只放入那種「無法被其他檔案所產生」的檔案。就像是系統的原始碼檔案,它們都是系統的「源頭」,我們是利用它們為基礎來產生之後的檔案。而像.o、.class、.exe之類,自然也就不應該被放到版本控制系統上。

此外,那些和個人本機端開發環境有關的檔案,例如IDE軟體的本地端設定檔,由於此檔案只關係到個別使用者自己的設定,不適用在所有開發者,所以也不適合放到團隊共有的版本控制系統上。

每當一個專案開始啟動之後,就可以在版本控制系統上建立檔案庫了。在專案的初期,專案的產出應該可能是一些像是專案計畫書、專案需求規格書等類型的文件。這些雖然不是程式的原始碼,但當然也有做版本管理的需要。

之後像是系統設計的產出,如系統設計的UML圖之類的檔案,也都應該納入版本控制的範圍之內。這一點十分的重要,因為像系統分析、系統設計的產物,即使在結束系統分析或系統設計的階段之後,它們在專案的進行過程中,仍然會因為需求的變動,或發現實作的困難之類的原因,而跟著連帶的改變,所以它們也會經歷版本的變遷。而且,更重要的是,基於我們要做需求追溯的原因,所以它們的版本變化及管理顯得更為重要。

所謂的「需求追溯」指的就是在開發系統時,我們會依據需求分析的結果,找出若干個需求項目,而我們會追溯這些需求項目之間的關係,以及需求項目與工作產出之間的關係。

前者即需求項目間交互參考的關係,即為所謂的「水平追溯」,而後者即為需求與工作產出之間的對應關係,即為所謂的「垂直追溯」。

對需求項目的這兩種追溯性力是開發時相當重要的。像需求的垂直追溯,可以協助我們找出每一個需求項目,究竟是否有對應的設計、實作、測試,以及找出當垂直線上的任一個產出有所變更時,它可能會影響到位在其上及其下的產出,又會有那一些部份。

當我們利用版本控制系統來管理這些工作產出時,實作的程式碼會有版本的變化,而實作的程式碼變化,也一定是連帶著關係到需求規格、系統分析,以及系統設計、系統測試等等階段中的產出。

例如,有可能是因為需求變更了,而連帶的使得之後的所有產出都跟著改變。這能夠相對應連貫的所有的產出,都是對齊到同一個版本。這也是進行組態管理的目標之一。

當我們利用版本控制系統的機制,可以取出被標記(tag)成特定標籤的原始碼版本時,我們也會希望一併取出該原始碼實作所垂直對應的系統分析文件,以及系統設計文件等其他階段的產出,因為它們和實作的原始碼間在任何一個時刻,都應該保持一致的關係。當我們取出某一版本的原始碼,我們也會需要察看這版本所對應之分析及設計。而這正可利用版本控制系統,來協助我們來達成組態管理的目標。

將所需檔案提交至檔案庫

了解應該將什麼類型的內容放到版本控制系統之後,讓我們來談談「提交」這個動作。

專案的每個參與成員的主要工作之一,便是為了達成工作的目標,而對對自己本機端的工作複本進行修改。而在做了修改之後,就便可以將修改的部份「提交(commit)」回檔案庫中。

「提交」動作當然很簡單,你只要在GUI上按下執行提交的按鈕,或是透過命令列操作輸入提交的命令即可,版本控制系統的客戶端程式,自然會將你所變更的檔案送至版本控制系統上。但是問題並不在操作,而是在其他的議題之上。

第一個議題是,你應該多久提交一次?每次提交的內容應該是什麼?

當然,你也可以自己一個人埋頭苦幹,將自己責任範圍內的程式碼,一次寫他個一個月,然後再來進行提交。可是這麼一來,你一次提交的範圍就很十分的大,這中間會涉及到非常多的功能的增加或是問題的修改。每一次提交的動作,其修改的內容,會被視為是一整個批次的變動。每次版本往前回溯的基本的單位,就是這一個批次的變動。當你提交的這一批次變動範圍太大時,就會使得版本追溯的粒度太大,要嘛整批接受你所做的變動,要嘛整批不接受,中間沒有其他的選項。

這樣的提交方式,除了造成版本追溯控制的困難之外,也有礙「連續整合」的原則。

現代的「敏捷開發」都講求「連續整合」,盡量降低加低每個開發成員間整合的時間週期。如此一來,彼此相依的部份可以及早開始整合,也能及早發現問題,開發中的系統也能持續在能運作的基礎上擴展。

如果你一個星期、甚至一個月才提交一次,那麼你手上的程式碼複本內容,和其他成員之間的落差就會太大,因為在你沒有提交的時間裡,其他成員也正如火如荼開發著,他們也同步在進行修改,但你始終是在一個過期基礎上開發,而且過期的情況會愈來愈嚴重。

而等你完成了一個大範圍的變動想要提交進系統時,往往會出現自己的部份和其他成員的部份難以整合,或是整合後發生問題,不然就是其他成員難以和你所做的修改做整合。甚至,如果你和其他成員共同修改了同一個檔案,也會因為落差太大,而導致自動合併的工具程式無法順利合併,必須倚靠人力介入。

因此,提交的範圍應該是愈小愈好、提交的週期則是愈短愈好。有一個比較理想的方式,便是以每個不可分割的單位功能、或修改做為提交的範圍。例如,一次的提交就是一個函式的完成,或是某個臭蟲的修改。

如此的粒度,對於掌控版本的回溯是很適合的,例如,你可以回溯到加入某個函式功能之前或是之後,也可以回溯到修正某個臭蟲之前或是之後。由於這樣的提交範圍也不會太大,所以也不致於造成和其他人開發進度的落差太大,因而衍生出整合的問題。

在決定提交的範圍之外,也要確定提交的品質。對於程式碼而言,雖然難以保證提交的都無臭蟲存在,但是總要確定所提交的程式碼,都能夠通過編譯。否則,如果將無法成功通過編譯的原始碼提交至版本控制系統上,也會連帶使得其他人受到影響,而無法正常編譯。

此外,不同的團隊可能會對提交的品質,設定更高的標準,例如,對於採用測試先行的團隊,可能就會要求必須在寫好單元測試程式的情況下,才能予以提交。

由上述的說明不難理解,僅管提交在操作上只是一個小小的動作,但是為了讓開發能真正的順暢並善用版本控制系統的優點,團隊還是應該訂立一些準則讓每個開發成員得以依循。

 

專欄作者

熱門新聞

Advertisement