3 我將用類比方式來介紹版本控制的概念。更嚴謹的解釋參見
4 http://en.wikipedia.org/wiki/Revision_control[維基百科版本修訂控制條目]。
8 我從小就玩電腦遊戲。相反,我只是在長大後才開始使用版本控制系統。我想我並不特
9 殊,並且,對比兩者工作方式可使這些概念更易解釋,也易於理解。
11 編寫代碼,或編輯文檔和玩遊戲差不多。在你做出了很多進展之後,你最好保存一下。
12 去做這個,會點擊你所信任的編輯器保存按鈕就好了。
14 但這將覆蓋老版本。就像那些學校裡玩的老遊戲,只有一個存檔:你確實可以保存,但
15 你不能回到更老的狀態了。這真讓人掃興,因為那個狀態可能恰好保存了這個遊戲特別
16 有意思一關,說不定哪天你想再玩一下呢。或者更糟糕的,你當前的保存是個必敗局,
21 在編輯的時候,如果想保留舊版本,你可以將檔案“另存為”一個不同的檔案,或在保
22 存之前將檔案拷貝到別處。你可能壓縮這些檔案以節省空間。這是一個初級的靠手工的
23 版本控制方式。遊戲軟件早就提高了這塊,很多都提供多個基于時間戳的自動存檔槽。
25 讓我們看看稍稍複雜的情況。比如你有很多放在一起的檔案,比如項目源碼,或網站文
26 件。現在如你想保留舊版本,你不得不把整個目錄存檔。手工保存多個版本很不方便,
29 在一些電腦遊戲裡,一個存檔真的包含在一個充滿檔案的目錄裡。這些遊戲為玩家屏蔽
30 了這些細節,並提供一個方便易用的界面來管理該目錄的不同版本。
32 版本控制系統也沒有兩樣。兩者提供友好的界面,來管理目錄裡的東西。你可以頻繁保
33 存,也可以之後加載任一保存。不像大多計算機遊戲,版本控制系統通常精於節省存儲
34 空間。一般情況如果兩個版本間只有少數檔案的變更,每個檔案的變更也不大,那就只
35 存儲差異的部分,而不是把全部拷貝的都保存下來,以節省存儲空間。
39 現在設想一個很難的遊戲。太難打了,以至于世界各地很多骨灰級玩家決定組隊,分享
40 他們遊戲存檔以攻克它。Speedrun們就是實際中的例子:在同一個遊戲裡,玩家們分別
43 你如何搭建一個系統,使得他們易於得到彼此的存檔?並易於上載新的存檔?
45 在過去,每個項目都使用中心式版本控制。某個伺服器上放所有保存的遊戲記錄。其他
46 人就不用了。每個玩家在他們機器上最多保留幾個遊戲記錄。當一個玩家想更新進度時
47 候,他們需要把最新進度從主伺服器下載下來,玩一會兒,保存並上載到主伺服器以供
50 假如一個玩家由於某種原因,想得到一個較舊版本的遊戲進度怎麼樣?或許當前保存的
51 遊戲是一個注定的敗局,因為某人在第三級忘記撿某個物品;他們希望能找到最近一個
52 可以完成的遊戲記錄。或者他們想比較兩個舊版本間的差異,來估算某個特定玩家幹了
55 查看舊版本的理由有很多,但檢查的辦法都是一樣的。他們必須去問中心伺服器要那個
56 舊版本的記錄。需要的舊版本越多,和伺服器的交互就越多。
58 新一代的版本控制系統,Git就是其中之一,是分散式的,可以被認作廣義上的中心式系
59 統。從主伺服器下載時玩家會得到所有保存的記錄,而不僅是最新版。這看起來他們好
62 最初的克隆操作可能比較費時,特別當有很長歷史的時,但從長遠看這是值得的。一個
63 顯而易見的好處是,當查看一個舊版本時,不再需要和中心伺服器通訊了。
67 一個很常見的錯誤觀念是,分散式系統不適合需要官方中心倉庫的項目。這與事實並不
68 相符。給誰照相也不會偷走他們的靈魂。類似地,克隆主倉庫並不降低它的重要性。
70 一般來說,一個中心版本控制系統能做的任何事,一個良好設計的分散式系統都能做得
71 更好。網絡資源總要比本地資源耗費更費。不過我們應該在稍後分析分散式方案的缺點,
74 一個小項目或許只需要分散式系統提供的一小部分功能,但是,在項目很小的時候,應
75 該用規劃不好的系統?就好比說,在計算較小數目的時候應該使用羅馬數字?
77 而且,你的項目的增長可能會超出你最初的預期。從一開始就使用Git好似帶著一把瑞士
78 軍刀,儘管你很多時候只是用它來開開瓶蓋。某天你迫切需要一把改錐,你就會慶幸你
83 對於這個話題,電腦遊戲的類比顯得不夠用。那讓我們再來看看文檔編輯的情況吧。
85 假設Alice在文檔開頭插入一行,並且Bob在文檔末尾添加一行。他們都上傳了他們的改
86 動。大多數系統將自動給出一個合理的處理方式:接受且合併他們的改動,這樣Alice和
89 現在假設Alice和Bob對檔案的同一行做了不同的改動。如果沒有人工參與的話,這個沖
90 突是無法解決的。第二個人在上載檔案時,會收到 _合併衝突_ 的通知,要麼用一個人
93 更複雜的情況也可能出現。版本控制系統自己處理相對簡單的情況,把困難的情況留給