當版本控制系統開始出現時,開發團隊中開發者之間合作的方式,是共用同一個「檔案庫(repository)」,無論這個檔案庫是在同一部工作站,或可透過網路存取的檔案系統上的本地端檔案庫,還是透過一個特定的通訊協定可以存取的遠端檔案庫,所有的成員都是共同存取同一份檔案庫。這種方式,就被稱為集中式(centralized)的版本控制系統。

集中式版本控制系統的特性
集中式的版本控制系統其實有三大重點,即同步、追溯、以及檔案的備份。

同步是為了讓所有開發者間對檔案所做的變更都能夠同步,最終得到相同的檔案內容。

而追溯,則是能夠回到受控檔案在變化歷史中的任何一個版本,並且明白每個版本間變化的原因、以及究竟做了什麼變動。

至於檔案的備份,無庸置疑的,就是讓所有的受控檔案集中保管於檔案庫中,做為備份也利於備份。不但能取得最新的版本,也能夠取出任意時間點上的版本。

所以說,從集中式版本控制系統的設計觀點來看,它主要是要維持開發者之間保持同步的狀態。若是依保持同步的手段再細分,又能衍生出兩種模式,一種是鎖定模式,而另一種則是合併模式。

在鎖定模式下,當開發者想要修改某檔案、簽出該檔案後,該檔案便會進入鎖定狀態,其他開發成員便無法加以修改,直到簽出者將該檔簽回為止。對於維持同步來說,這當然是一個十分保險的作法,因為永遠不會有兩個或以上的開發者同時修改同一個檔案。只是,這種方法造成了開發者對於檔案修改的互斥效應,使得開發效率受到影響。

因此,許多版本控制系統採用合併模式,在合併模式下,允許多位開發者同時針對同一檔案進行修改,當他們分別將檔案提交回集中的檔案庫時,若發生衝突的情況,便會自動進行合併,而若自動合併失敗,再要求人工進行衝突的調解。不過即使如此,最終的目的,還是試圖要維持諸開發者間的同步。畢竟,版本控制的結果在集中式檔案庫中是唯一的,也是每位開發者都需與此結果保持一致的。

集中式版本控管系統的缺點

集中式的檔案控制系統對控制系統的設計來說,當然是比較簡單的,因為所有和版本控制有關的重要資訊,幾乎都可以集中在系統上控管。不過,它在本質上也具備一些缺點,使得分散式的檔案控制系統得以應運而生,甚至開始慢慢成為主流。

集中式的檔案控制系統使用起來會有什麼問題呢?首先,由於檔案庫是集中控管,因此幾乎都是在透過網路可連結的主機之上,開發者想要自檔案庫中取得資訊或檔案、想要將檔案提交至檔案庫,或是對檔案庫做一些其他的操作,都必須在能夠連網的環境下進行。

這會影響版本控制系統為開發者提供支援及協助的時間。例如,你已經在本地端做好了必要的修改,想要提交到系統上,卻因為正處於無法連網的環境,所以無法將檔案提交出去。

當然,或許你會想,可以等到能聯網之後才提交就好了。但是,還記得在前文中也提到,我們希望每次提交的變更都是一個不可分割的最小單位,若因無法連網,無法將已完成的修改提交出去,那麼也就無法繼續修改其他的項目,因為這將會使得,應該被分為多次提交的內容混在一塊了。

在一些開放原始碼的社群裡,有些開發者處在一些連網環境、速度較不佳的地區,每次存取那些位處遠處之集中檔案庫中的資訊(例如修改歷史),就會耗去大量的時間,而這也有礙於開發的效率。

再者,由於每個開發者的修改,時常是反覆持續進行,即使都在處理同一問題,也有可能未到穩定、完備到足以提供其他開發者使用的程度,若是在修改的過程中即提交至集中的檔案庫上,那麼,便有可能讓集中檔案庫中的檔案,處於不穩定、不成熟的狀態。當然,也可以讓開發者持續修改至足夠穩定完備後,再將修改內容提交至檔案庫。但是,在這個空窗期裡,開發者就無法得到版本控制系統的支援,他沒有辦法將修改過程中的不同階段,畫分成為多個版本,使得他仍然可以從版本控制系統中得到好處。

分散式版本控制系統的特性

基於以上以及其他種種的好處,分散式的版本控制系統開始興起,並且普及流行。

分散式的版本控制系統和集中式的版本控制系統,最大的差別在於,分散式的版本控制系統的檔案庫允許不只一份,事實上,每個開發者都可以在自己的一部或多部開發機器上建立檔案庫。

雖然你或許會認為都是將受控的檔案儲存在本地端,但其實檔案庫和檔案在本地端的工作複本有很大的差別,其中最重要的意義就是在於版本管理有關的資訊、例如提交訊息、版本變化的記錄等等,在分散式的版本控制系統中,都可以記錄在每一個檔案庫上,也因此,所以對版本控制系統的操作,都可以直接在本機端的檔案庫中進行,包括提交、分支、等等的操作。

對分散式版本控制系統來說,精神不在於維持不同開發者間的同步,而是讓每個開發者擁各自獨立的變更集合,開發者之間可分享自己的變更集合。

在分散式的版本控制系統下,開發者可以進行「推(push)」的動作,其意義即將自身檔案庫中的變更(在其他檔案庫擁有者的授權之下)送至其他的檔案庫,也可以進行「拉(pull)」的動作。

因為每個開發者都可以擁有獨立的檔案庫,所以可以直接對自己的檔案庫進行操作。開發者不僅可以在離線的環境(例如飛機或高鐵之上)不中斷,連續工作,也可以持續進行修改,一方面獲得版本控制系統的支持(可以管理版本、查詢修改歷史、可以回溯、也可以持續提交寫下記錄訊息、……),另一方面也不需要將自己的修改,持續送至集中的檔案庫上,造成了其他開發者必須套用這些修改,引起可能的不穩定情況。

因為分散式版本控制系統本質的關係,使得此類系統更重視對分支(branch)的支援,它們通常有較好的分支及合併的能力。像現在一個極受歡迎的分散式版本控制系統Git的使用者,就很習慣廣泛、大量的進行分支,來輔助日常的工作流程。

有了分散式的檔案庫及更強大的分支管理、合併,因而衍生多種工作流程,像是集中式(Centralized)、整合管理者式(Integration-Manager)、司令官及副官(Dictator and Lieutenants)等等。

集中式就是所有的人共用檔案庫,都能夠隨意的存取檔案庫。而在整合管理式的工作流程下,僅有少數的整合管理者,被授權對檔案庫做推的動作,其他的開發者僅能利用「請求拉(request pull)」,請求整合管理者將其所做修改納入。如果你的團隊想施行經程式碼審核後方能進到所謂的「blessed」 檔案庫時,便可在此模式下進行。

若是更大規模的專案(常見於大型的開放原始碼專案),則可採所謂「司令官及副官(Dictator and Lieutenants)」的工作流程。在此流程下,唯一的一名司令官將系統畫分為多個子系統,分別授權予個別的副官,去管理各子系統的變更整合,而司令官則為最上層的整合者,有權利決定從這些副官的所做的變更拉至中心檔案庫,接著再推至blessed檔案庫,以供其他人開發者由此進行複製的動作。

不同的開發團隊依其需求及應用情境,可以適用不同的工作流程,現行的分散式控制系統提供的機制,很多都可以彈性滿足你的需要,最重要的是你要明白自己所需的究竟是那種模式,以及如何利用這些機制來構成所需的模式。

 

作者簡介


Advertisement

更多 iThome相關內容