2016 年 03 月 01 日

DVCS分散式的版本控制圖解說明

這篇DVCS(Distributed Version Control System)的文章, 深入淺出, 已徵得原文作者的同意, 在此將他的文章翻譯為中文.

distributed_logo

傳統的版本控制輔助檔案的備份,追蹤與同步. 分散式的版本控制讓變更的分享簡單容易. 如果你做的對, 你可以魚與熊掌兼得: 簡單的合併同時並可以集中版本發佈.

要分散式的嗎? 一般的版本控制到底發生什麼問題?

沒有問題 — 如果你想快速回憶的話請參考VCS版本控制視覺指引 . 當然, 有些人可能會嘲笑你還在用"古老"的系統. 但在我看來仍然是OK的: 對於任何專案來說有用版本控制系統總是正向的一步.

集中的版本控制系統在1970年代出現, 當初程式設計者有了精簡型終端機(thin clients)但同時也羨慕又大又貴又快速的"big iron" mainframes(誰能不被當時風行的大小通吃8bits到1 byte的機器吸引呢?)

集中管理是簡單的概念, 很自然是第一步想到的:讓每個人到同一個地方簽入簽出, 就像集中到某個圖書館的書本上註記一樣.

如此的做法對於備份,復原和同步行得通, 不過對變更的合併與分支卻不太行. 當專案成長時, 通常會想將功能切割, 獨立開發與測試, 再逐步將變更併入主開發線. 實際做時, 分支就很麻煩, 新的功能可能要做龐大的簽入, 如果中間有任何差錯, 變更變得很難管理也很難做問題排解. 當然, 集中控管的系統也總有"可能"做合併, 但並不容易: 你需要親自確實追蹤合併的動作與內容, 以避免同樣的變更被做兩次. 分散式的版本控制系統讓分支與合併無痛執行, 因為這是此類系統的長處. (譯註: SVN支援Merge Tracking後就可以避免同樣的變更會合併兩次以上的問題)

請看一些示意圖

別的教學多是嚴肅的命令列指令, 在此提供您視覺化的說明. 讓你回想一下運用典型集中控管的版本庫的狀況:

centralized_example

每個人與主開發線同步也將檔案簽入主開發線: Sue加入soup, Joe加入juice, Eve加入eggs. Sue的變更必須先簽入主開發線才會被其他人看到. 的確, 理論上, Sue可以另開一個新的分支讓其他人測試她的變更, 可是在一般的版本控制系統(VCS)如此做很麻煩.

分散式版本控制系統(DVCS)

分散式模式, 每位開發者有他們自己的版本庫. Sue的變動存在她的工作電腦的版本庫,她可以決定是否要跟Joe或Eve分享:

distributed_example

不過是否有可能像群龍無首一樣? 不會的, 如果想要的話, 每個人可以將他的變動上傳(push)給同一個版本庫, 令人感到執疑地, 這不就跟上面講的集中式版本控制管理一樣. 這個版本庫(包含了Sue, Joe和Eve的變動.

我希望分散式版本控制DVC(distributed version control)可以有不同的名稱, 如 “獨立的(independent)”, “聯合的(federated)” 或 “點對點的(peer-to-peer)”. 此字 “分散”讓人聯想到分散式運算, 工作被分派給一群機器(如尋找外星智慧訊號的 SETI@home {可參考SETI@home台灣網站} 或做 蛋白質摺疊分析Protein folding).

而DVCS並不像Seti@home: 每一端(node)是各自獨立的且是否分享由各工作端自我決定(在Seti, 你必須回覆你的結果)

5分鐘說明主要觀念

此給你基本概念; 如果你有興趣, 可參考相關patch theory的說明書 .

核心概念

    • 集中式版本控制聚焦於同步,追溯(tracking), 和備份檔案.
    • 分散式版本控制聚焦於變動分享; 每一變更有其 全域唯一辨識碼(guid-global unique id)或unique id.
    • 記錄/下載以及採用一個變更被視為分別的步驟 (在集中式系統, 此三者同時發生).
    • 分散式系統沒有強制的架構. 你可以建立"中央管理"區或讓個人保持在自己的工作端運作.

新術語

  • 推(push): 將變更送給其他的版本庫 (也許需要權限)
  • 拉(pull): 從另一版本庫下載同步檔案變更

主要的優點

  • 每個人都有自己的沙盒(local sandbox). 你可以在自己的工作電腦上修改或回覆前版, 不需要大量的簽入. 你自己的工作記錄都累積存在自己的版本庫.
  • 可離線工作. 你只有當你想分享變更時才需要上線. 否則你可隨你高興一直在自己的工作電腦上獨立作業, 簽入或復原, 沒有所謂"伺服器"當掉或在飛機上無法上網的問題.(譯者註: 現在有些國際線的飛機上付費後可以上網)
  • 速度很快. 差異(diff), 提交源碼與變更回復都在本地端即可完成. 沒有因網路或伺服器不穩而必須要求使用一年前舊版本的問題. (譯者註: 作者應該是指伺服器OS版本與版本控制版本匹配的問題)
  • 可妥善做變動的處理. DVCS針對分享的變更做建置. 每個變更都有其獨一無二的辨識碼(GUID)以方便追蹤.
  • 分支與合併很容易. 因為每一開發人員"有自己的分支", 每一分享的變動就像交換整合(reverse integration). 但獨一無二的辨識碼(GUID)讓自動合併變更與避免重複合併動作變的簡單容易.
  • 較少的管理. DVCS很容易部署; 不需要安裝“一直運作的”伺服器軟體. 此外, DVCS也不太需要你去"加"新的使用者; 你只是去選擇你想從那裡拉(pull)版本庫的URLs. 這樣可以避免大型專案中令人頭痛的政治性問題.

主要的缺點

  • 仍需要備份. 有個說法是你的“備份”就是其他人有你變更資料的終端機資訊. 我無法認同—如果這些其他人終端機資料並沒有採用你所有的變更呢? 或是當你變更的時候他們都不在線上? 用DVCS, 你仍希望可以有台機器讓你push所有的變更到他那裡保存“以防萬一”. (在Subversion, 你有一台隨時待命的機器做主要的資料貯存庫, 建議您在DVCS也做一樣的事).
  • 沒有所謂的“最近的版本”存在. 如果沒有集中地, 你無法馬上知道是否要到Sue, Joe或Eve那取得最近變更的版本(version). 再者, 一個中央集中的檔案庫才可幫助大家清處地知道最近的"穩定版本"為何.
  • 沒有真正的修訂版號碼(revision numbers). 每一版本庫有依變更做出的修訂版號碼. 和傳統的集中式版本庫不同的做法是人們依變更的修訂號碼做溝通: “請問你有變更號碼 fa33e7b? " (這個變更號碼GUID 似乎長的不太好看). 還好, 你可以用有意義的名稱標示你發佈的版本.

Mercurial 快速上手(Quickstart)

Mercurial速度很快,是個簡易的DVCS. 暱稱是hg, 就像水銀(Mercury)元素一樣.
cd project
hg init                                (create repo here)
hg add list.txt                        (start tracking file)
hg commit -m "Added file"              (check file into local repo)
hg log                                 (see history; notice guid)

changeset:   0:55bbcb7a4c24
user:        Kalid@kazad-laptop
date:        Sun Oct 14 21:36:18 2007 -0400
summary:     Added file

[edit file]
hg revert list.txt                 (revert to previous version)

hg tag v1.0                        (tag this version)
[edit file]
hg update -C v1.0                  ("update" to the older tagged version; -C forces overwrite of local copy)
2011-12-08_1513
一旦Mercurial已經初始化一個目錄, 看起來將如下:
distributed_repo_layout

你將有:

  • 一個工作拷貝(working copy). 你正在編輯的檔案群.
  • 一個版本庫. 一個目錄(Mercurial的.hg)包含所有的補釘(patches)以及可演譯資料(metadat:comments, guids, dates, etc.). 因為沒有集中的伺服器, 所以這些資料都放在你這裡.
在我們的分散式案例, Sue, Joe和Eve有他們各自的版本庫, 儲存他們不相干的修訂版歷史資料(revision histories).

 

理解更新(Updates)與合併(Merging)

在研究DVCS時有幾項讓我有些混淆. 第一, 有幾步將造成更新(updates)

  • 取得變更到版本庫:推(pushing) 或 拉(pulling)
  • 採用變更到檔案中:更新(update) 或 合併(merging)
  • 儲存新版:簽入/提交源碼(commit)

第二, 依據變更, 你可以更新或合併:

  • 當無模糊地帶時,更新(Updates)發生. 譬如, 我將變更拉(pull)到一直以來都是你在編輯的檔案. 因沒有重疊的變更,檔案將跳到最近的修訂版(revision).
  • 當我們的變更發生衝突時,就有必要合併(Merge). 如果我們兩個都去編輯檔案,最後會變成兩個"分支", 類似平行宇宙(alternate universes-多種假設同時發展的各個故事)的樣子. 有個我修改的世界, 也有個你修改的世界. 在此例, 我們可能想要合併成一個單一的宇宙.
我仍在整理DVCS到底可多容易的產生分支與摺疊分支:
distributed_merge

在此案,因為 (+Soup) 和 (+Juice) 為同一個母項(parent-僅一個 “Milk”的列表)的變更, 有必要做合併(merge). 經過Joe合併檔案後, Sue可以做一般的 “pull和update” 即可獲得Joe已合併的結果. 她不需要親自做合併的動作. .

在Mercuril, 你可如下執行:

hg incoming ../another-dir  (see pending changes)
hg pull ../another-dir      (download changes)

hg update                   (actually apply changes...)
hg merge                    (... or merge if needed)

hg commit                   (check in merged file; unite branches)

2011-12-08_1529

是的, “pull-merge-commit” 周期蠻長的. 幸運地, Mercurial有整合多指令(commands)為單一的捷徑. 雖說看起來好像蠻複雜的, 但仍比在Subversion手動合併簡單多了.

大多數的合併是自動完成的. 當發生衝突時, 一般可以很快被解決. Mercurial持續追蹤每一變更的母/子關係(我們的合併列表有兩個母項), 與"最新版(heads)"或每一分支的最近變動. 在合併前我們有兩個heads;之後, 一個.

組織一分散式專案

此為一種組織方式:

distributed_push_pull

Sue, Joe和Eve將變更加入一共同的分支. 他們可以跟任一人交易補丁(patches)來做"兄弟建置(buddy builds)":嘿 老兄, 請問要試試這些補丁嗎? 在推給實驗分支(experimental branch)前,我需要看看此是否可行.

然後, 經維護守門員在看過,將實驗分支的變更拉到穩定的分支(stable branch), 此有最近的版本. 分散式的版本控制系統(DCVS)幫助每一變更獨立進行, 但也提供集中系統所有的"單一來源(single source)". 有多種開發的模式可用, 如"pull only",此只有維護守門員決定是否要從別人拿取變更資料, Linux的開發採用此種,或"shared push", 此和集中管理的系統作業模式很類似. DVCS讓您彈性選擇要採用哪種方法來維護您的專案.

練習和嚴厲批評以臻至善

我是DVCS新手,但很高興分享我目前已瞭解的. 我覺得SVN很好用, 但覺得去了解如何可以讓合併簡單容易也有趣. 我的建議是你可以從Subversion起步, 感受一下什麼是團隊協同作業,再實驗分散式的模式. 如果你適當的籌劃, DVCS可以達到集中控管系統的效果, 你也同時可享有簡易合併的好處.

線上資源

從Linus演說影片節錄:

    • “How many have done a branch and merged it? How many of you enjoyed it?”
    • “When you do a merge, you plan ahead for a week, then set aside a day to do it.”
    • “Some people have 5, 10, 15 branches”. One branch is experimental. One branch is maintenance, etc.
    • “CVS — you don’t commit. You make changes without committing. You never commit until it passes a giant test suite. People make 1-liner changes, knowing it can’t possibly break.”

所以呢…. 祝好運囉, 密切注意聖戰狀況…

Soft & Share在Facebook有經營兩個粉絲團, 歡迎來加入

喜歡我們的分享嗎? 記得使用以下社群分享按鈕分享給您的社群朋友吧!

Join the conversation! 2 Comments

  1. […] 以上是基礎資料 — 隨著時間我將分享我從做my projects學到的東西. 現在你已了解一般的版本控制系統(VCS),也可以看看 an illustrated guide to distributed version control (DVCS分散式版本控制系統圖解說明). […]

    喜歡

    回應
  2. […] DVCS分散式的版本控制圖解說明 幾年前翻譯的文章, 裡面那幾張圖對於剛接觸DVCS會很容易了解跟VCS的不同, 現在還有人在用VCS嗎? DVCS Git應該已經變成了顯學, 不過這份文件當年在翻譯的時候DVCS有兩大主流, 一個是Git, 一個是Mercurial,裡面的範例是用Mercurial, 以目前來看Git應該是大獲全勝 […]

    喜歡

    回應

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

分類

未分類