歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> Linux 的版本控制

Linux 的版本控制

日期:2017/2/27 9:24:12   编辑:更多Linux
版本控制系統或資源管理系統是現代軟件開發的一個重要方面。不使用版本控制系統就如同超速駕駛一輛汽車:很刺激,也可能會更快抵達目的地,但事故卻在所難免。本文概述了軟件配置管理(SCM)系統及其優勢,內容涵蓋 CVS、Subversion、Arch 和 Git。本文還討論了最常見的 SCM 體系結構。本文在最後給出了新出現的一些方法及這些方法與先前方法的區別。

什麼是軟件配置管理?

在學校學習的重要工具中,通常不會 包含 SCM。軟件(或資源)控制,正如其名字所暗示的那樣,是一種工具和一種相關的過程,而這種過程被用於維護源代碼及其演進。SCM 提供的主要功能如下:

在存儲庫(repository)中維護一個文件。 在存儲庫中維護文件的修訂。 檢測源更改沖突並為多個開發人員的環境提供合並。 跟蹤變更的發起方。 為了實現一致、可重復的構建提供文件(相關修訂)的配置管理。 SCM 的適用性資源控制 主要是指源代碼和相關文件的控制,而資源管理 則可應用於任何類型的資源。包含超文本標記語言(Html)和二進制圖像文件、一般文本文檔或其他任何文件的 Web 站點是 SCM 系統進行修訂控制的對象。

所以,SCM 允許您控制存儲庫中的一組文件並跟蹤這些文件的修訂。其他開發人員更改了存儲庫中的這些文件後,SCM 會標識出這些變更與您所做的變更之間存在的沖突,然後自動將其合並或通知您存在沖突。這個功能非常重要,因為它允許多個開發人員修改同一組文件。SCM 還能跟蹤出誰做了何種變更。SCM 還允許您將文件按邏輯劃分為相關的文件組,比如組成軟件圖像或可執行文件的源文件。

SCM 的術語

在深入研究 SCM 體系結構的類型和細節之前,先要熟悉一下術語的含義。存儲庫 是文件存儲和管理的中心位置(有時又被稱為樹)。從存儲庫中取出文件放到本地系統的工作文件夾的過程被稱作簽出。如果變更了本地文件而又想同步變更存儲庫,就需要執行更新。如果要將變更後的文件簽入到存儲庫,就需執行提交。如果所變更的文件先前已經被變更並已由別人提交,則會發生合並,表明兩組變更集將會被合並在一起。若由於變更沖突的原因不能合並時,則必已發生了沖突。在此情況下,提交被拒絕,並要求開發人員手工合並變更。當提交了變更之後,就會創建此文件的一個新的修訂。

一個或多個開發人員可以對主樹(存儲庫的當前頭)或位於主樹旁的單個的分支進行操作。這就讓開發人員可以操作分支而不會影響到主樹。當分支穩定後,再將分支與主樹進行合並。

要標記源樹演進過程中的重要階段,可以對一組文件修訂應用標簽。這會將這組文件組合成一個有用的集合(有時會用作針對於惟一構建的文件的一個發布)。

體系結構

各種 SCM 間有許多的差異,其中有兩種最基本的區別很值得研究:

集中式存儲庫與分布式存儲庫 變更集模型與快照模型

集中式存儲庫與分布式存儲庫

現代 SCM 體系結構的最為重要的差異之一是存儲庫是集中式的還是分布式(分散的)。當前最為常見的體系結構是集中式存儲庫。這個星型 體系結構由中心的源存儲庫和工作於這個存儲庫的多個開發人員組成(參見圖 1)。開發人員從中心存儲庫簽出源代碼到本地的沙箱內,進行變更後,將它提交回中心存儲庫。其他開發人員就可以再訪問這些變更。

圖 1. 在集中式體系結構中,所有開發人員都通過同一個中心存儲庫進行工作

中心存儲庫也可以創建分支,允許多個開發人員協作於針對位於存儲庫(但必須在 mainline 或 tip 之外)的資源的一組變更。

分布式體系結構則允許開發人員為其變更創建其自己本地的存儲庫。本地開發人員的存儲庫與原始的存儲庫(已被分布)很相似。主要的區別是:在集中化的方式中,變更是在沙箱內完成的,而在分布式方法中則允許開發人員工作於分離的存儲庫。開發人員進行變更、提交變更到其本地的存儲庫,之後,在不影響主干的前提下,與其他開發人員的變更合並。這樣,本地開發人員就使得變更集對上線(upline)開發人員可用(參見圖 2)。

圖 2. 在分散體系結構中,開發人員通過其各自的存儲庫員同步工作

分散體系結構很有意思,因為它允許不同的開發人員在對等網絡內同步工作。當工作准備好(最好是穩定)後,開發人員可以分發變更集(或修補)以使他人也可以使用這些特性。這是當今許多開源系統的模型,包括 Linux® 內核。

變更集模型與快照模型

早先的和現代的 SCM 的體系結構的另一個有趣的區別是 delta 變更的存儲方式。它們理論上是相同的,且產生的結果也相同,但在修訂的存儲方式上二者卻大不相同。

在快照模型中,整個存儲庫的每個修訂(帶優化以減少樹的大小)的全部文件都被存儲。而在變更集模型中,只有 delta 被存儲於修訂之間,這樣就創建了一個精簡的存儲庫(參見圖 3)。

圖 3. 快照模型和變更集模型各有所長

從圖 3 可以看出,模型不同但結果卻相同。在快照模型中,可以快速獲得修訂,但需要更多的空間來存儲它們。而變更集模型需要的空間少,但需要更多時間來獲得某個修訂,原因是 delta 必須應用於基本修訂。在本文後面的部分將介紹如何建立優化來最小化必須要應用的 delta 的數量。

示例 SCM

讓我們來看一下按體系結構(集中或分布)劃分的一些 SCM。您很快就會看到,其中一些 SCM 支持兩種模型。

CVS

並發版本系統(Concurrent Versions System,CVS)是當今最為常用的 SCM。它是一種集中式的解決方案,采用了快照模型,開發人員使用集中式的存儲庫來進行軟件的協作開發。CVS 十分常見而且是 Linux 發布版的一部分。其簡單和方便的語法(對大多數人而言)使其迅速成為了多個或單個開發人員 SCM 的一種理想選擇。

清單 1 給出了一組 CVS 命令示例和簡短的相關描述。要獲得關於 CVS 的更多信息,請參閱 參考資料 部分。

清單 1. CVS 命令示例

# Create a new repository cvs -d /home/user/new_repository init # Connect to the central repository eXPort CVSROOT=:pserver:[email protected]:/cvs_root # Check out a sandbox for module project from the central repository cvs checkout project # Update a local sandbox from the central repository cvs update # Check in changes from the local sandbox to the central repository cvs commit # Add new files to the local sandbox (need to be committed) cvs add <file/subDirectory> # Show changes made in the local sandbox cvs diff

對於喜歡用指向-單擊方式操作的用戶,CVS 提供了許多開源的圖形化前端以供使用,包括 WinCVS 和 TortoiseCVS(集成了 Microsoft® Windows Explorer)。

盡管 CVS 被廣泛采用,但它仍然有一些不足之處。CVS 不允許重命名文件,而且對一些特殊文件(如 symlink)的支持不是很好。變更可以按文件跟蹤,而非按變更本身,這點十分討厭。合並有時也會出現問題(CVS 內部會為此使用 diff3)。

然而,CVS 總體而言還是很有用的,能夠實現其需要實現的任務,而且所有主流的平台都支持 CVS。如果喜歡用 CVS 而又想回避其缺點,則可以考慮使用 Subversion。

Subversion

Subversion(SVN)是為了替代 CVS 而設計的,消除了 CVS 原有的問題和缺點。與 CVS 一樣,Subversion 也是一種集中化的解決方案,采用的是快照模型。它的命令也模仿了 CVS 的,但增加了一些對諸如刪除文件、重命名文件或恢復為原始文件等的處理功能。

Subversion 還允許遠程訪問,可以采用很多協議,比如超文本傳輸協議 (HTTP)、安全 HTTP或定制的 SVN 協議,此協議還支持通過 Secure Shell (SSH)的隧道技術。

清單 2 給出了 Subversion 所支持的一些命令及 CVS 中所沒有的一些擴展。要獲得關於 Subversion 的更多信息,請參閱 參考資料 部分。很明顯,Subversion 的命令集和 CVS 的很相似,這使它極受 CVS 用戶的歡迎。

清單 2. Subversion 的命令示例

# Create a new repository svnadmin create /home/user/new_repository # Check out a sandbox from the central repository svn checkout file:///server/svn/existing_repository new_repository # Update a local sandbox from the central repository svn update # Check in changes from the local sandbox to the central repository svn commit # Add new files to the local sandbox (need to be committed) svn add <file/subdirectory> # Show changes made in the local sandbox svn diff # Rename a file in the local sandbox (requires commit to the repository) svn rename <old_file> <new_file> # Remove files (also removed from repository, requires commit) svn delete <file/subdirectory>

與 CVS 一樣,Subversion 集成了一些圖形化的前端如 ViewCVS 和 TortoiseSVN。另外也有一些工具可以把 CVS 存儲庫轉化為 Subversion(例如 cvs2svn.py),但這些工具並不能處理復雜版本的分支和標記。和許多開源項目一樣,隨著時間的推移,這種情況會有所改變。Subversion 還集成了 TortoiseMerge 作為一個單獨的查看器和修補程序。

Subversion 解決了許多讓 CVS 用戶困擾的問題,比如特殊文件的版本化和自動的提交和簽出。如果您喜歡用 CVS 和集中式存儲庫的方式,那麼 Subversion 就是您所需的 SCM。

現在讓我們先放下對集中方式的討論,看看被人們視為 SCM 未來的協作式分散存儲庫。

Arch

Arch 是分散 SCM 的規范,它提供許多不同的實現,包括 ArX、Bazaar、GNU arch 和 Larch。Arch 不僅可以作為一種分散 SCM 運作,如 圖 2 所示,還可使用變更集模型(參見 圖 3)。 Arch SCM 是開源開發的一種很流行的方法,因為開發人員可在單獨的存儲庫上進行開發,同時又能夠控制全部資源。這是因為分布式存儲庫就是具有修訂控制的實際存儲庫。可以在本地存儲庫利用變更創建一個修補來供上游的開發人員使用。這就是分散模型的真正的強勢所在。

與 Subversion 相似,Arch 解決了 CVS 中所存在的許多問題,包括元數據的變更,例如修訂文件許可、處理文件刪除和重命名以及自動的簽入(將簽入組在一起而非作為單獨的文件)。

清單 3 中顯示了 Arch SCM 中的一些常見命令,還給出了 GNU arch,因為它是由 Arch 的設計者 Tom Lord 開發的。GNU arch 提供了 SCM 應有的一些基本功能,包括 Subversion 中的一些新特性。

清單 3. GNU arch (tla) 的命令示例

# Register a public archive tla register-archive http://www.mtjones.com/arch # Check out a local repository from the upstream repository tla get [email protected]/project--stable myproject # Update from the local repository tla update # Check in changes to the local repository tla commit # Add new files to the local repository (need to be committed) tla add <file> # Show changes made in the local repository (patch format) tla what-changed # Rename a file in the local repository (requires commit to the repository) tla mv <old_file> <new_file> # Remove files (also removed from repository, requires commit) tla rm <file>

Arch 還允許用 star-merge 合並來自上游存儲庫的變更。為了最小化必須應用到基本修訂的修補的數量(根據變更集模型), cacherev 命令將會在存儲庫中創建基本修訂的一個新的快照。

創建基本修訂的一個新快照

Arch 的優勢之一是雖然它是為分散操作所設計的,但也可以用於集中存儲庫范例。

tla 用戶對其不滿之處是它太過復雜。其他的 Arch 實現,例如 baz 則非常簡單。如果 tla 不能滿足要求,可以嘗試使用後者。

現在讓我們來看一下最後一個分散式的 SCM,它由 Linux 內核的維護者 Linus Torvalds 本人編寫。

Git

Git SCM 由 Linus Torvalds 開發,用來替代 Bitkeeper SCM(參閱 參考資料 部分)。 它非常簡單,是一種分散式的基於變更集的 SCM 且用作 Linux 內核的 SCM。它使用文件組模型而非跟蹤單個的文件。使用 SHA1 壓縮並混編變更集以驗證其完整性(參見清單 4)。

清單 4. Git 的命令示例

# Get a Git repository (first time) git clone \ rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ linux-2.6 rsync -a \ --progress rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/ \ .git/ # Update a Git repository from the defined upstream Git repository git pull rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git # Checkout from the Git repository into the local working repository git checkout # Update from the local Git repositor3 git-update-cache # Commit changes to the local Git repository git commit # Add new files to the local repository git-update-cache --add <file> # Show changes made to the local working directory git diff # Remove files (requires commit) git-update-cache --remove <file>

Git SCM 在其自己的 Git 存儲庫內是自托管的,這意味著您必須引導 Git 來將其安裝到本機。Git 的命令集與您到目前為止看到的那些命令十分類似,而且相對簡單。

您可能會問:“為什麼不使用現有的 SCM 中的一種呢?” 問得很好。 Git 非常有趣,吸引著許多 Linux 內核黑客,所以它很可能成為下一個主流的 SCM。Linus 將 Git 描述為一個高速的目錄內容管理器,雖然它所做的工作不多但完成得十分高效。

收益

無論您使用何種 SCM,都會獲得一些普遍的收益。使用 SCM,可以跟蹤文件中的變更來判斷變更對軟件的影響程度。當發生不正確的變更時,可以發現這些變更並將它們恢復回原始資源中。可以組合文件修訂集並標記它們來制作發布,而發布又可以在任何時間簽出以供重復構建代碼的特定發布(SCM 的要求)。

不管使用集中式存儲庫還是分布式存儲庫,使用快照模型還是變更集模型,所帶來的收益都是相同的。因為任何現代軟件開發項目都必須要有 SCM,所以越早越多地使用它們就會受益越多。

前景展望

本文只討論了現在最為常用的 SCM 的一些最基礎的知識。還有許多其他的開源 SCM 可以使用,例如 Aegis、Bazaar-NG、DARCS 和 Monotone。當然,SCM 也引起了一些爭論,而這些爭論通常很難有正確的答案。如果使用一種工具後效率極高,那就使用這種工具吧!SCM 大多時候都用在團隊開發的情況下,而很少用於孤立的個人開發的環境中(除非您是個獨斷專行的老板,喜歡自己做所有決定)。所以,您盡可以嘗試所有的可能性來熟悉一些不同的風格。SCM 是軟件開發中的必需工具,也是您的開發工具箱中的必備部分。




Copyright © Linux教程網 All Rights Reserved