所有版本控制系統都必須解決相同的基本問題:系統如何允許使用者共享資訊,同時防止他們不小心互相干擾?使用者非常容易在儲存庫中意外覆蓋彼此的變更。
考慮以下情境:假設我們有兩位同事,Harry 和 Sally。他們各自決定同時編輯同一個儲存庫檔案。如果 Harry 先將他的變更儲存到儲存庫,那麼 Sally 就有可能(在稍後)不小心用她自己檔案的新版本覆蓋它們。雖然 Harry 的檔案版本不會永遠遺失(因為系統會記住每個變更),但 Harry 所做的任何變更 將不會 出現在 Sally 較新的檔案版本中,因為她從未見過 Harry 的變更。Harry 的工作仍然有效地遺失了 - 或至少在檔案的最新版本中遺失了 - 而且很可能是意外造成的。這絕對是我們想要避免的情況!
許多版本控制系統使用 鎖定-修改-解鎖 模型來解決這個問題,這是一個非常簡單的解決方案。在這樣的系統中,儲存庫只允許一次一人變更檔案。首先 Harry 必須 鎖定 檔案,然後才能開始對其進行變更。鎖定檔案很像從圖書館借書;如果 Harry 鎖定了檔案,那麼 Sally 就無法對其進行任何變更。如果她嘗試鎖定檔案,儲存庫將拒絕請求。她所能做的就是讀取檔案,並等待 Harry 完成他的變更並釋放他的鎖定。在 Harry 解鎖檔案後,他的回合結束了,現在 Sally 可以透過鎖定和編輯來輪到她了。
鎖定-修改-解鎖 模型的問題在於它有點限制性,並且經常成為使用者的障礙
鎖定可能會導致管理問題。 有時 Harry 會鎖定一個檔案然後忘記它。同時,因為 Sally 仍在等待編輯檔案,所以她束手無策。然後 Harry 去度假了。現在 Sally 必須找管理員來釋放 Harry 的鎖定。這種情況最終導致很多不必要的延遲和時間浪費。
鎖定可能會導致不必要的序列化。 如果 Harry 正在編輯文字檔的開頭,而 Sally 只是想編輯同一個檔案的結尾呢?這些變更根本不重疊。他們可以輕鬆地同時編輯檔案,並且不會造成太大的損害,假設變更已正確合併在一起。在這種情況下,他們沒有必要輪流。
鎖定可能會產生虛假的安全感。 假設 Harry 鎖定並編輯檔案 A,而 Sally 同時鎖定並編輯檔案 B。但是假設 A 和 B 彼此依賴,並且對每個檔案所做的變更在語義上不相容。突然之間,A 和 B 不再一起工作。鎖定系統無力阻止這個問題 - 但它不知何故提供了一種虛假的安全感。Harry 和 Sally 很容易想像,透過鎖定檔案,每個人都開始了一項安全、隔離的任務,因此阻止了他們及早討論他們不相容的變更。
Subversion、CVS 和其他版本控制系統使用 複製-修改-合併 模型作為鎖定的替代方案。在這個模型中,每個使用者的客戶端讀取儲存庫並建立檔案或專案的個人 工作副本 。然後使用者並行工作,修改他們的私有副本。最後,私有副本合併在一起成為一個新的最終版本。版本控制系統通常會協助合併,但最終,人類有責任使其正確發生。
這是一個例子。假設 Harry 和 Sally 各自建立同一個專案的工作副本,從儲存庫複製而來。他們同時工作,並在他們副本中的同一個檔案 A
中進行變更。Sally 先將她的變更儲存到儲存庫。當 Harry 稍後嘗試儲存他的變更時,儲存庫會通知他他的檔案 A 已 過時。換句話說,儲存庫中的檔案 A 自他上次複製以來已發生某種變更。因此 Harry 要求他的客戶端 合併 來自儲存庫的任何新變更到他的檔案 A 工作副本中。Sally 的變更很可能與他自己的變更沒有重疊;因此一旦他整合了兩組變更,他就會將他的工作副本儲存回儲存庫。
但是,如果 Sally 的變更 確實 與 Harry 的變更重疊怎麼辦?那又怎麼樣?這種情況稱為 衝突,而且通常不是什麼大問題。當 Harry 要求他的客戶端將最新的儲存庫變更合併到他的工作副本中時,他的檔案 A 副本會以某種方式標記為處於衝突狀態:他將能夠看到兩組衝突的變更,並在它們之間手動選擇。請注意,軟體無法自動解決衝突;只有人類有能力理解並做出必要的明智選擇。一旦 Harry 手動解決了重疊的變更(也許是透過與 Sally 討論衝突!),他就可以安全地將合併後的檔案儲存回儲存庫。
複製-修改-合併 模型聽起來可能有點混亂,但實際上,它運行得非常順暢。使用者可以並行工作,永遠不必等待彼此。當他們在同一個檔案上工作時,事實證明他們的大部分並行變更根本不重疊;衝突很少發生。而且解決衝突所需的時間遠少於鎖定系統所損失的時間。
歸根結底,一切都歸結為一個關鍵因素:使用者溝通。當使用者溝通不良時,語法和語義衝突都會增加。沒有任何系統可以強迫使用者完美地溝通,也沒有任何系統可以檢測語義衝突。因此,不要被鎖定系統將以某種方式防止衝突的虛假承諾所迷惑是沒有意義的;在實踐中,鎖定似乎比其他任何事物都更能抑制生產力。
在一個常見的情況下,鎖定-修改-解鎖 模型表現更好,那就是當您有無法合併的檔案時。例如,如果您的儲存庫包含一些圖形圖像,並且兩個人同時變更圖像,則無法將這些變更合併在一起。Harry 或 Sally 其中一人將會遺失他們的變更。