集中式版本控制與分散式版本控制——Git 學習筆記01

ARM的程式設計師敲著詩歌的夢發表於2020-04-04

什麼是版本控制

如果你用 Microsoft Word 寫過東西,那你八成會有這樣的經歷:

想刪除一段文字,又怕將來這段文字有用,怎麼辦呢?有一個辦法,先把當前檔案“另存為”一個檔案,然後繼續改,改到某個程度,再“另存為”一個檔案。就這樣改著、存著……最後你的 Word 文件變成了這樣:

這裡寫圖片描述

過了幾天,你想找回被刪除的文字,但是已經記不清儲存在哪個檔案了,只能挨個去找。真麻煩,眼睛都花了。看著一堆亂七八糟的檔案,真想把不用的都刪除,只保留一個終極版,可是又怕哪天會用上,還不敢刪,真愁人。

這時候你想,要是有一個軟體能幫你記錄每一個版本,並且能顯示出各個版本之間的差異,那多方便啊。幸運的是,這樣的軟體還真有,git 就是其中一個。

git 不僅具備記錄版本、比較差異等最基本的功能,還支援分支、離線開發、多點開發…… 總之 git 有非常豐富而強大的功能等著你去學習與發現。如果說你學習 git 是為了收穫一縷春風,那麼最後你得到的將是整個春天。

集中式版本控制(Centralized Version Control )

開發者之間的合作方式是共用一個倉庫(repository),無論這個倉庫是在本地還是在遠端,只要是所有成員都共同存取同一個倉庫,那麼這種方式就是集中式(centralized)版本控制。

集中式版本控制的特點

集中式的版本控制系統其實有三大重點,即同步、追溯、以及檔案的備份。
同步是為了讓所有開發者對檔案所做的變更都能夠同步,最終得到相同的檔案內容。

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

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

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

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

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

集中式版本控制的缺點

集中式版本控制系統使用起來會有什麼問題呢?

首先,開發者想要簽出程式碼、提交到倉庫,或是對檔案庫做一些其他的操作,都必須在能夠連網的環境下進行。這會大大降低開發效率。例如,你已經在本地端做好了必要的修改,想要提交到系統上,卻因為正處於無法連網的環境,所以無法將檔案提交出去。

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

如果有的開發者處在一些連網環境、速度較不佳的地區,每次存取倉庫中的資料都會耗去大量的時間,這也是非常有礙效率的。

再者,由於每個開發者的修改,時常是反覆持續進行,在修改的過程中,總會遇到未能穩定、完備到足以提供其他開發者使用的程度,若是在此時提交到倉庫,便有可能讓倉庫的程式碼處於不穩定、不成熟的狀態。當然,也可以讓開發者持續修改至足夠穩定完備後,再將修改內容提交至倉庫。但是,在這個空窗期裡,開發者就無法享受到版本控制的好處,他沒有辦法將修改過程中的不同階段,劃分成為多個版本。

分散式版本控制(Distributed Version Control)

由於集中式版本控制系統有一些致命的缺點,分散式(或分散式)版本控制系統應運而生,甚至慢慢成為主流。

分散式版本控制系統和集中式版本控制系統,其最大差別在於前者的倉庫可以有多份。事實上,每個開發者都可以在自己的一臺或者多臺電腦上建立檔案庫。

雖然你可能認為二者都是將受控的檔案儲存在本地端,但其實檔案庫檔案在本地端的工作複本還是有很大差別的。其中最重要的意義在於檔案庫中包含了完整的版本管理資料、例如提交資訊、版本變化記錄等等。因此,所有對版本控制系統的操作,都可以直接在本機端的檔案庫中進行,包括提交、分支、合併、回退等。

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

在分散式版本控制系統中,開發者可以進行“推”(push)的動作,其意義是將自身檔案庫中的變更送至其他的檔案庫;也可以進行“拉”(pull)的動作,其意義是獲取其他檔案庫的變更。

因為每個開發者都擁有獨立的檔案庫,所以可以直接對自己的檔案庫進行操作。在離線環境中,開發者既可以連續工作,也可以持續修改,和本地檔案庫進行互動(比如管理版本、查詢修改歷史、回溯、提交、……)。另一方面,開發者不需要將自己的修改持續送至集中的檔案庫上,造成其他開發者必須套用這些修改,引起可能的不穩定情況。

因為分散式版本控制系統本質的關係,使得此類系統更重視對分支(branch)的支援,它們通常有較好的分支及合併的能力。git 非常提倡我們利用分支來輔助日常工作流程。

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


參考資料

[1] https://www.ithome.com.tw/node/77088
[2] https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

相關文章