分散式版本控制

分散式運算

程式設計中,分散式版本控制(英語:distributed revision controldistributed version control,又譯為分布式版本控制),又稱去中心化版本控制decentralized version control),是一種版本控制的方式,它允許軟體開發者可以共同參與一個軟體開發專案,但是不必在相同的網路系統下工作。其作法是在每個開發者電腦中複製一份完整的代碼庫以及完整歷史[1]。因此在無法連接網路時,仍可以進行軟體的分支合併,可以加速大部份的作業,增加此情形可以進行的工作,而且系統的代碼庫可以在多家電腦上備份,不需靠單一位置的備份[1][2][3][4]。而多個位置的代碼庫再透過其他機制來達到同步。

以分散式版本控制方法,作出的軟體版本控制系統,稱為分散式版本控制系統(distributed revision control system,縮寫為DRCS,或是distributed version control system,縮寫為DVCS)。著名的分散式版本控制系統有Monotone、Git等。

分散式和集中式版本控制系統的比較

分散式版本控制系統(DVCS)用對等網路的作法來處理版本控制,而集中式版本控制系統則是用主從式架構的作法。分散式版本控制系統同步各軟件存儲庫的方式是用對等網路的方式傳送Patch。在代碼庫中沒有單一的中央版本,每一個用戶都有工作複本以及完整的變更歷史。

和集中式版本控制系統相比,分散式版本控制系統的優點如下:

  • 用戶在沒有網路的情形下,也可以存取其電腦中的軟件存儲庫。
  • DVCS下的常見工作(例如上傳、看修改履歷、回退變更)不需要和中央伺服器通訊即可達成,因此速度很快[5]。DVCS下,只有要和其他人分享變更內容時才需要通訊。
  • 允許個人作業,使用者可以將不希望公開的早期修改(甚至是草稿)上傳[來源請求]
  • 工作複本的作用類似遠端備份,因此不會依賴單一的實體機器,帶來單點失效的風險[5]
  • 允許不同的開發模型,例如用分支或Commander/Lieutenant模型[來源請求]
  • 自由及開放源代碼軟件專案中,若有管理上的衝突或是設計上的不一定,很容易可以從一專案中分叉出新的專案。

和集中式版本控制系統相比,分散式版本控制系統的缺點如下:

  • 一開始複製軟件存儲庫會比較慢,因為預設設值會複製所有的分支以及版本歷史。
  • 缺乏了集中式版本控制系統中有的鎖定機能,針對一些無法用版本控制系統合併的二進位檔案(例如圖形檔),或是太複雜的二進位或XML檔案(例如office文件、PowerBI檔、SQL Server Data Tools BI軟體等)[來源請求]
  • 每一個使用者都需要備份所有的資料、分支及版本歷史,因此需要額外的儲存空間[6]
  • 各軟件存儲庫內容不一定同步。

有些版本控制系統原來是集中式的,但也會加入一些分散式的特點。例如Subversion的許多機能可以在沒有網路時執行[7]Visual Studio Online和Visual Studio Team Services除了集中式的版本管理外,也支援用Git進行的分散式版本控制。

也有些分散式版本控制系統設法要改善取出(checkout)時間以及儲存成本的問題,例如微軟開發的Git虛擬文件系統就可以在很大的代碼庫下運作[8],會提供一個虛擬檔案系統,只在有需要時才會下載檔案到電腦中。

工作模式

分散式版本控制比較適合大型專案,有一部份由獨立的工作者所開發,像是Linux核心計劃,因為開發者可以獨立工作,可以提交其合併修改(或是拒絕他人的合併修改)。分散式模型的靈活性可以配合客製化的程式碼產生工作流程。最常使用的是整合式工作流英語integrator workflow。在集中型的模型中,開發者需要將其工作串列化,以避免不同版本之間的問題。

中心存儲庫及分支存儲庫

每一個專案都有中心存儲庫,一般也是官方的存儲庫,會用專案維護者管理。開發者會複製中心存儲庫的內容,建立本地存儲庫。開發者再定期確認中心存儲庫的修改內容,使本地存儲庫和中心存儲庫同步。

開發者在本地存儲庫建立新的分支,在分支上修改程式碼。在開發完成之後,再將修改內容整合到中心存儲庫。

拉取請求

在分散式版本控制的軟體中,若要修改軟體,一般會用「拉取請求」(pull request)來進行,也稱為「合併請求」(merge request)[9]。貢獻者請專案維護者「拉取」修改的軟體內容(因此稱為拉取請求),若此修改內容應該成為正式代碼庫的一部份,就需要合併拉取請求中提到的軟體內容[10]

開發者在有新的軟體變更時,會提出「拉取請求」,告訢專案維護者有新的軟體變更。一般而言每一個拉取請求會有對應的討論串,可以針對軟體修改的內容進行討論(代碼審查)。可以存取存儲庫的人都可以看到提交的拉取請求。專案維護者可以接受或是拒絕拉取請求的內容[11]

若拉取請求經過審查,已被核可,就會合併到存儲庫中。依工作流程的不同,有可能在加入這段程式的軟體版本正式發行前,進行軟體的測試。因此,有些專案會有一個特殊的分支,合併未測試的拉取請求[10][12]。也有些專案會有自動化測試平台,執行並測試每一個拉取請求的內容,可能會用持續整合工具(例如Travis CI),再由審查者檢查新的程式碼測試覆蓋率是否足夠。

歷史

第一代的開源分散式版本控制系統有GNU archMonotoneDarcs英語Darcs,不過開源的分散式版本控制系統一開始並不太流行,直到GitMercurial發佈後才流行。

在2002年至2005年時,Linux內核的開發是透過BitKeeper[13]Git會推出的原因就是因為BitKeeper的公司收回了給Linus Torvalds及Linux核心開發者的免費軟體授權[13]

相關條目

參考文獻

  1. ^ 1.0 1.1 Chacon, Scott; Straub, Ben. Getting Started – About Version Control. Pro Git 2nd. Apress. 2014. Chapter 1.1 [4 June 2019]. (原始內容存檔於2020-12-20). 
  2. ^ Spolsky, Joel. Distributed Version Control Is Here to Stay, Baby. Joel on Software. 2010-03-17 [4 June 2019]. (原始內容存檔於2016-11-27). 
  3. ^ Intro to Distributed Version Control (Illustrated). www.betterexplained.com. [7 January 2018]. (原始內容存檔於2020-11-09). 
  4. ^ What Is Git ? – Explore A Distributed Version Control Tool. www.edureka.co. [7 January 2018]. (原始內容存檔於2020-10-12). 
  5. ^ 5.0 5.1 O'Sullivan, Bryan. Distributed revision control with Mercurial 請檢查|url=值 (幫助). [July 13, 2007]. (原始內容存檔於2009-02-20). 
  6. ^ What is version control: centralized vs. DVCS. www.atlassian.com. [7 January 2018]. (原始內容存檔於2020-10-30). 
  7. ^ OSDir.com. Subversion for CVS Users :: OSDir.com :: Open Source, Linux News & Software. OSDir.com. [2013-07-22]. (原始內容存檔於2016-08-23).  |url-status=|dead-url=只需其一 (幫助)
  8. ^ Jonathan Allen. How Microsoft Solved Git's Problem with Large Repositories. 2017-02-08 [2019-08-06]. (原始內容存檔於2020-05-20). 
  9. ^ Sijbrandij, Sytse. GitLab Flow. GitLab. 29 September 2014 [4 August 2018]. (原始內容存檔於2019-09-26). 
  10. ^ 10.0 10.1 Johnson, Mark. What is a pull request?. Oaawatch. 8 November 2013 [27 March 2016]. (原始內容存檔於2020-06-16). 
  11. ^ Using pull requests. GitHub. [27 March 2016]. (原始內容存檔於2019-01-28). 
  12. ^ Making a Pull Request. Atlassian. [27 March 2016]. (原始內容存檔於2020-02-06). 
  13. ^ 13.0 13.1 McAllister, Neil. Linus Torvalds' BitKeeper blunder. InfoWorld. [2017-03-19]. (原始內容存檔於2015-08-26) (英語). 

外部連結