第 1 章 入門

2018-02-24 15:45 更新

我將用類比方式來介紹版本控制的概念。更嚴(yán)謹(jǐn)?shù)慕忉寘⒁?維基百科版本修訂控制條目。

工作是玩

我從小就玩電腦游戲。相反,我只是在長(zhǎng)大后才開始使用版本控制系統(tǒng)。我想我并不特 殊,并且,對(duì)比兩者工作方式可使這些概念更易解釋,也易于理解。

編寫代碼,或編輯文檔和玩游戲差不多。在你做出了很多進(jìn)展之后,你最好保存一下。 去做這個(gè),會(huì)點(diǎn)擊你所信任的編輯器保存按鈕就好了。

但這將覆蓋老版本。就像那些學(xué)校里玩的老游戲,只有一個(gè)存檔:你確實(shí)可以保存,但 你不能回到更老的狀態(tài)了。這真讓人掃興,因?yàn)槟莻€(gè)狀態(tài)可能恰好保存了這個(gè)游戲特別 有意思一關(guān),說不定哪天你想再玩一下呢?;蛘吒愀獾模惝?dāng)前的保存是個(gè)必?cái)【郑?這樣你就不得不從頭開始玩了。

版本控制

在編輯的時(shí)候,如果想保留舊版本,你可以將文件“另存為”一個(gè)不同的文件,或在保 存之前將文件拷貝到別處。你可能壓縮這些文件以節(jié)省空間。這是一個(gè)初級(jí)的靠手工的 版本控制方式。游戲軟件早就提高了這塊,很多都提供多個(gè)基于時(shí)間戳的自動(dòng)存檔槽。

讓我們看看稍稍復(fù)雜的情況。比如你有很多放在一起的文件,比如項(xiàng)目源碼,或網(wǎng)站文 件?,F(xiàn)在如你想保留舊版本,你不得不把整個(gè)目錄存檔。手工保存多個(gè)版本很不方便, 而且很快會(huì)耗費(fèi)巨大。

在一些電腦游戲里,一個(gè)存檔真的包含在一個(gè)充滿文件的目錄里。這些游戲?yàn)橥婕移帘?了這些細(xì)節(jié),并提供一個(gè)方便易用的界面來管理該目錄的不同版本。

版本控制系統(tǒng)也沒有兩樣。兩者提供友好的界面,來管理目錄里的東西。你可以頻繁保 存,也可以之后加載任一保存。不像大多計(jì)算機(jī)游戲,版本控制系統(tǒng)通常精于節(jié)省存儲(chǔ) 空間。一般情況如果兩個(gè)版本間只有少數(shù)文件的變更,每個(gè)文件的變更也不大,那就只 存儲(chǔ)差異的部分,而不是把全部拷貝的都保存下來,以節(jié)省存儲(chǔ)空間。

分布控制

現(xiàn)在設(shè)想一個(gè)很難的游戲。太難打了,以至于世界各地很多骨灰級(jí)玩家決定組隊(duì),分享 他們游戲存檔以攻克它。Speedrun們就是實(shí)際中的例子:在同一個(gè)游戲里,玩家們分別 攻克不同的等級(jí),協(xié)同工作以創(chuàng)造驚人戰(zhàn)績(jī)。

你如何搭建一個(gè)系統(tǒng),使得他們易于得到彼此的存檔?并易于上載新的存檔?

在過去,每個(gè)項(xiàng)目都使用中心式版本控制。某個(gè)服務(wù)器上放所有保存的游戲記錄。其他 人就不用了。每個(gè)玩家在他們機(jī)器上最多保留幾個(gè)游戲記錄。當(dāng)一個(gè)玩家想更新進(jìn)度時(shí) 候,他們需要把最新進(jìn)度從主服務(wù)器下載下來,玩一會(huì)兒,保存并上載到主服務(wù)器以供 其他人使用。

假如一個(gè)玩家由于某種原因,想得到一個(gè)較舊版本的游戲進(jìn)度怎么樣?或許當(dāng)前保存的 游戲是一個(gè)注定的敗局,因?yàn)槟橙嗽诘谌?jí)忘記撿某個(gè)物品;他們希望能找到最近一個(gè) 可以完成的游戲記錄。或者他們想比較兩個(gè)舊版本間的差異,來估算某個(gè)特定玩家干了 多少活。

查看舊版本的理由有很多,但檢查的辦法都是一樣的。他們必須去問中心服務(wù)器要那個(gè) 舊版本的記錄。需要的舊版本越多,和服務(wù)器的交互就越多。

新一代的版本控制系統(tǒng),Git就是其中之一,是分布式的,可以被認(rèn)作廣義上的中心式系 統(tǒng)。從主服務(wù)器下載時(shí)玩家會(huì)得到所有保存的記錄,而不僅是最新版。這看起來他們好 像把中心服務(wù)器做了個(gè)鏡像。

最初的克隆操作可能比較費(fèi)時(shí),特別當(dāng)有很長(zhǎng)歷史的時(shí),但從長(zhǎng)遠(yuǎn)看這是值得的。一個(gè) 顯而易見的好處是,當(dāng)查看一個(gè)舊版本時(shí),不再需要和中心服務(wù)器通訊了。

一個(gè)誤區(qū)

一個(gè)很常見的錯(cuò)誤觀念是,分布式系統(tǒng)不適合需要官方中心倉(cāng)庫(kù)的項(xiàng)目。這與事實(shí)并不 相符。給誰(shuí)照相也不會(huì)偷走他們的靈魂。類似地,克隆主倉(cāng)庫(kù)并不降低它的重要性。

一般來說,一個(gè)中心版本控制系統(tǒng)能做的任何事,一個(gè)良好設(shè)計(jì)的分布式系統(tǒng)都能做得 更好。網(wǎng)絡(luò)資源總要比本地資源耗費(fèi)更費(fèi)。不過我們應(yīng)該在稍后分析分布式方案的缺點(diǎn), 這樣人們才不會(huì)按照習(xí)慣做出錯(cuò)誤的比較。

一個(gè)小項(xiàng)目或許只需要分布式系統(tǒng)提供的一小部分功能,但是,在項(xiàng)目很小的時(shí)候,應(yīng) 該用規(guī)劃不好的系統(tǒng)?就好比說,在計(jì)算較小數(shù)目的時(shí)候應(yīng)該使用羅馬數(shù)字?

而且,你的項(xiàng)目的增長(zhǎng)可能會(huì)超出你最初的預(yù)期。從一開始就使用Git好似帶著一把瑞士 軍刀,盡管你很多時(shí)候只是用它來開開瓶蓋。某天你迫切需要一把改錐,你就會(huì)慶幸你 所有的不單單是一個(gè)啟瓶器。

合并沖突

對(duì)于這個(gè)話題,電腦游戲的類比顯得不夠用。那讓我們?cè)賮砜纯次臋n編輯的情況吧。

假設(shè)Alice在文檔開頭插入一行,并且Bob在文檔末尾添加一行。他們都上傳了他們的改 動(dòng)。大多數(shù)系統(tǒng)將自動(dòng)給出一個(gè)合理的處理方式:接受且合并他們的改動(dòng),這樣Alice和 Bob兩人的改動(dòng)都會(huì)生效。

現(xiàn)在假設(shè)Alice和Bob對(duì)文件的同一行做了不同的改動(dòng)。如果沒有人工參與的話,這個(gè)沖 突是無(wú)法解決的。第二個(gè)人在上載文件時(shí),會(huì)收到?合并沖突?的通知,要么用一個(gè)人 的改動(dòng)覆蓋另一個(gè)的,要么完全修訂這一行。

更復(fù)雜的情況也可能出現(xiàn)。版本控制系統(tǒng)自己處理相對(duì)簡(jiǎn)單的情況,把困難的情況留給 人來處理。它們的行為通常是可配置的。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)