分布式和集中式版本控制工具-svn,git,mercurial比较分析
現(xiàn)象,近年來,我們對(duì)版本控制工具的關(guān)注點(diǎn)似乎正在改變.起初,我們主要也是唯一的目的就是對(duì)代碼進(jìn)行監(jiān)控,使我們能夠安全的返回到舊的版本,以便我們能夠診斷代碼中的問題.后來,我們的關(guān)注點(diǎn)更側(cè)重于如何使人與人之間的合作更為順暢. 這個(gè)關(guān)注點(diǎn)并不是要取代對(duì)代碼的監(jiān)控,而是以代碼監(jiān)控為基礎(chǔ),并建立于其上的.現(xiàn)在,我們又越來越關(guān)注使用這些工具來描述代碼的變更,因此就出現(xiàn)了對(duì)于重寫代碼歷史命令(history rewriting command)的需求.當(dāng)然,對(duì)代碼變更的描述也同樣需要建立在前兩種關(guān)注點(diǎn)之上.
我們可以把版本控制工具的應(yīng)用分為六個(gè)層次:
0. 沒有版本控制
完全沒有版本控制的解決方案,或者就使用一個(gè)共享的文件系統(tǒng),并對(duì)其做定期的備份.一個(gè)開發(fā)人員,或者最多幾個(gè)開發(fā)人員在沒有工具的情況下共享代碼,其面臨的風(fēng)險(xiǎn)可想而知:
- 在任何時(shí)刻,代碼可能都是不兼容的.
- 代碼可能會(huì)由于開發(fā)人員的錯(cuò)誤面丟失.
- 如果開發(fā)人員想要改寫覆蓋他人所做的修改,那再容易不過了.
1. 初步的探索
- 開發(fā)人員擁有了網(wǎng)絡(luò)上的工作空間,他們無法在線下工作.
- 運(yùn)行一次代碼構(gòu)建也許就意味著有時(shí)間可以去好好吃一頓了.
- 重構(gòu)即使能夠進(jìn)行,也慢的要死.
- checkout代碼可能需要一整夜.
- checkin代碼也很慢.
- 沒有原子提交.
- Branching和Tagging操作的代價(jià)昂貴.
- 個(gè)人或是本地建立branch就意味著再次的checkout.
- 集中式的,而不是公布式的.
- 合并點(diǎn)的跟蹤很慢或是根本無法使用.
- 這時(shí)的工具還沒有辦法理解重命名的合并.
- 代碼庫有時(shí)會(huì)崩潰,需要較高的專家/開發(fā)人員比例,如1:10.
這時(shí)的工具有了基本的版本控制功能,如checkout,版本記錄和鎖文件.通常這就意味著開發(fā)人員在同一份代碼上工作,而代碼的同步就會(huì)依賴于每個(gè)人代碼文件的鎖狀態(tài).這種工具在擴(kuò)展和長期工作上都會(huì)有問題.對(duì)資源的重命名難到幾乎不可能完成.Branching和Tagging操作則會(huì)需要同時(shí)操作三份代碼的權(quán)限,而且可能還需要一個(gè)宰好的或者兩柱香.如, VSS.
2. 笨拙
- 開發(fā)人員有了本地的拷貝,并且可以在線下工作.
- 本地的文件系統(tǒng)意味著構(gòu)建的速度大大提升.
- 重構(gòu)的時(shí)間只夠喝杯茶了.
- checkout的速度已經(jīng)非常快了.
- checkin也許還是慢一點(diǎn).
- 仍然沒有原子提交.
- Branching和Tagging代價(jià)仍然昂貴.
- 集中式的,不是分布式的.
- 合并點(diǎn)的跟蹤很慢或是根本無法使用.
- 沒有辦法合并重命名文件,需要在提交前使用一些擴(kuò)展的跟進(jìn)沖突解決機(jī)制.
- 代碼庫有時(shí)會(huì)崩潰,專家/開發(fā)人員比例已經(jīng)得到優(yōu)化,如1:20.
如CVS和TFS.
3. 基本成型
- 開發(fā)人員擁有本地拷貝并且可以在線下工作.
- 在本地文件系統(tǒng)上可以進(jìn)行快速的構(gòu)建.
- 可以快速的重構(gòu).
- checkout和checkin的速度都會(huì)非常的快.
- 終于有了原子提交.
- 輕量級(jí)的Branching和Tagging操作.
- 基本的合并操作.
- 個(gè)人/本地的branching操作仍然需要再次checkout.
- 因?yàn)槿匀皇羌惺降?而不是分布式的.
- 基本的合并點(diǎn)追蹤.
- 沒有辦法合并重命名文件,需要在提交前使用一些擴(kuò)展的跟進(jìn)沖突解決機(jī)制.
- 代碼庫有時(shí)會(huì)崩潰,專家/開發(fā)人員比例已經(jīng)很低,如1:100.
如Subversion.
4. 有效并且可靠
- 開發(fā)人員擁有本地拷貝并且可以在線下工作.
- 在本地文件系統(tǒng)上可以進(jìn)行快速的構(gòu)建.
- 可以快速的重構(gòu).
- checkout和checkin的速度都會(huì)非常的快.
- 無操作的代碼同步和更新非常的快速.
- 終于有了原子提交.
- 輕量級(jí)的Branching和Tagging操作.
- 高級(jí)的Branching和合并操作.
- 個(gè)人/本地的branching操作仍然需要再次checkout
- 因?yàn)槿匀皇羌惺降?而不是分布式的.
- 完善的合并點(diǎn)追蹤.
- 合并重命名文件只能通過配置好的branch映射來實(shí)現(xiàn),否則就需要在提交前進(jìn)行修訂.
- 代碼庫很少會(huì)崩潰,專家/開發(fā)人員比例非常低,如1:1000.
如Perforce.
5. 高速,無形,高度可用
- 開發(fā)人員擁有本地拷貝并且可以在線下工作.
- 在本地文件系統(tǒng)上可以進(jìn)行快速的構(gòu)建.
- 可以快速的重構(gòu).
- checkout和checkin的速度都會(huì)非常的快.
- 無操作的代碼同步和更新非常的快速.
- 終于有了原子提交.
- 輕量級(jí)的Branching和Tagging操作.
- 高級(jí)的Branching和合并操作.
- 非常高效的個(gè)人/本地branching操作.
- 分布式的,而不是集中式的.
- 完善的合并點(diǎn)追蹤.
- 無縫合并重命名文件,無需任何配置.
- 代碼庫很少會(huì)崩潰,專家/開發(fā)人員比例幾乎為零,如1:10000.
如Git和Mercurial.
通過前面版本控制工具的演化過程,我們基本上可以看到分布式工具的特點(diǎn)和優(yōu)勢了.相對(duì)于以往的客戶-服務(wù)器端的集中式系統(tǒng),它所采用的是一種P2P的方式.客戶端不再需要從一個(gè)單一的中央代碼庫同步代碼,每一個(gè)端點(diǎn)的代碼的拷貝都是真正的代碼庫.分布式的版本控制系統(tǒng)是通過端點(diǎn)之間交換補(bǔ)丁(patch)的方式來同步代碼的,而這種方式就決定了分布式系統(tǒng)與集中式系統(tǒng)的幾個(gè)重要的區(qū)別:
- 默認(rèn)情況下,沒有標(biāo)準(zhǔn)的代碼庫參照;只有工作代碼的拷貝.
- 由于不需要與中央服務(wù)器進(jìn)行通信,因此一般的操作(如提交,查看歷史和還原修改等)的執(zhí)行速度非常快.只有在向其它端點(diǎn)push代碼更改或者從其它端點(diǎn)pull代碼更改的時(shí)候才會(huì)需要進(jìn)行通信.
- 每一份代碼拷貝都可以作為代碼庫及其更改歷史的一份遠(yuǎn)程備份,這就為數(shù)據(jù)丟失提供了天然的保護(hù).
- 鼓勵(lì)測試性的branch - 創(chuàng)建或者銷毀branch的操作簡單而且快速.
- 同伴之間的合作變得非常容易
現(xiàn)在的項(xiàng)目用的是Subversion做版本控制,但是我們自己用的是git-svn,這里主要通過這兩種有代表性的工具來比較一下集中式和分布式工具的優(yōu)勢.
Subversion提倡單一的中央代碼庫模型,不提倡大規(guī)模的branching.在一個(gè)使用持續(xù)集成的環(huán)境中,其實(shí)也就是我們每天工作的環(huán)境,這個(gè)模型是非常合適的.這也是Subversion為什么這么流行,應(yīng)用范圍這么廣的原因之一.
雖然分布式的系統(tǒng)使你擁有足夠的靈活性來自己安排自己的工作流程,但是其實(shí)大多數(shù)人的工作模式仍然是使用持續(xù)集成,這也就意味著需要一條可以共享的代碼庫主線.現(xiàn)在的版本控制系統(tǒng)已經(jīng)有了神奇的合并工具,但這些合并仍然只限于文本.所以對(duì)于語義上的一致,仍然需要持續(xù)集成來保證.結(jié)果就是即使一個(gè)團(tuán)隊(duì)在使用分布式的版本控制系統(tǒng),他們?nèi)匀粫?huì)需要一個(gè)主版本庫.
即使如此,分布式系統(tǒng)仍擁有一些SVN無法提供的體驗(yàn).
- 在分布式管理系統(tǒng)中,你可以在自己本地磁盤上擁有代碼庫的完整拷貝,對(duì)代碼庫的操作不需要通過網(wǎng)絡(luò)向中央服務(wù)器進(jìn)行請(qǐng)求,因此速度會(huì)非常的快.特別是你在進(jìn)行查看日志,與舊版本代碼進(jìn)行比較或者其它需要完整代碼庫的操作時(shí),這種速度上的改善會(huì)非常明顯.對(duì)于集中式的系統(tǒng),在局域網(wǎng)內(nèi)你也許只會(huì)覺得有點(diǎn)慢,但如果當(dāng)你工作在一個(gè)分布式的項(xiàng)目中,你的代碼庫在另一個(gè)大洲的時(shí)候,這就會(huì)是非常大的問題了.
- 如果你經(jīng)常在四處奔走,無法隨時(shí)與代碼庫建立網(wǎng)絡(luò)連接,那么一個(gè)分布式的管理系統(tǒng)會(huì)使你可以隨時(shí)與代碼庫一起工作.你可以隨時(shí)隨地提交你的工作,瀏覽歷史,并且在比較版本間的差異.
- 還有一項(xiàng)體驗(yàn)也許并不能說是一個(gè)工具問題,而更多的是一個(gè)社會(huì)問題.分布式版本控制工具鼓勵(lì)快速的branching和試驗(yàn).在SVN中,你當(dāng)然也可以進(jìn)行branching操作,但是你所做的操作對(duì)于其它在這個(gè)代碼庫上工作的人員也是可見的, 這也許并不是什么大問題,但確實(shí)會(huì)降低人們進(jìn)行一些實(shí)驗(yàn)性工作的欲望.分布式系統(tǒng)則會(huì)鼓勵(lì)你為工作代碼進(jìn)行記錄:你可以向你的本地代碼庫提交未完成的修改,甚至是無法通過測試和無法編譯的代碼.你同樣可以在SVN中進(jìn)行這些操作,但是在公共空間中創(chuàng)建這些branches總是讓人望而卻步.
在某種特定情況下,SVN也有其相應(yīng)的優(yōu)勢,如果你需要對(duì)版本控制系統(tǒng)難以合并的二進(jìn)制文件(如word文檔或者ppt)進(jìn)行管理的話,你就應(yīng)該回退到獨(dú)占式checkout的鎖機(jī)制下,這就需要一個(gè)集中式的系統(tǒng).另外,SVN更容易上手:你有一個(gè)代碼庫,所有的更改都指向這個(gè)代碼庫,如果你知道如何創(chuàng)建,提交以及checkout,那你就可以開始使用它了,而像branching,更新這些操作在使用過程中自然也就慢慢熟悉了.SVN擁有一些非常好用的客戶端軟件,而且?guī)缀跛械闹髁鱅DE都有與SVN集成的插件,這些都能夠?yàn)槟闶褂肧VN提供很大的幫助.
Git則增加了復(fù)雜性,似乎總是有兩種模式來進(jìn)行操作,checkout和clone, commit和push...... 你得知道哪些命令是針對(duì)本地進(jìn)行操作的,哪些命令是對(duì)服務(wù)器或者是主代碼庫進(jìn)行操作的. 實(shí)際上,Git的命令和思維模式與其它的版本控制系統(tǒng)是有所不同的.Bulter Cole曾這樣形容Git:"它是一個(gè)神奇的功能強(qiáng)大的東西,它幾乎可以做任何你讓它做的事情,只有你知道如何讓它做".Git的反對(duì)者也會(huì)抱怨Git缺少可發(fā)現(xiàn)性,你很難從它的表面設(shè)計(jì)推斷出它的行為.而Git的支持者則認(rèn)為這只是因?yàn)镚it使用了不同于其它系統(tǒng)的思維模式,你需要先忘掉以前那些關(guān)于版本控制系統(tǒng)的知識(shí)才能更好的來欣賞Git.無論如何,Git對(duì)于那些喜歡研究事物內(nèi)部工作機(jī)制的人來說,還是非常有吸引力的.
通常來講,Git相比Mercurial在處理branching方面表現(xiàn)更好,尤其是用于試驗(yàn)和檢查點(diǎn)的短期branch.Mercurial提倡是另一種機(jī)制,例如快速的clone一份代碼庫或者是使用補(bǔ)丁,但是Git的branching模式更為簡單好用.Mercurial在處理大型二進(jìn)制文件時(shí)同樣有問題.通常的建議是使用SVN來管理二進(jìn)制文件,如果你只有很少的二進(jìn)制文件需要管理,不值得建立單獨(dú)的管理機(jī)制的話,Mercurial將就著也能處理.
此外Git之所以能在網(wǎng)絡(luò)上引起如此多的共鳴,有一個(gè)很大的原因是Git對(duì)于開源項(xiàng)目來說是完善的選擇.你可以新建一個(gè)項(xiàng)目分支,向你自己的項(xiàng)目分支提交修改,然后讓項(xiàng)目維護(hù)人員將你的修改pull過去.有了Git,這一切就變得如此的方便和自然.即使你沒有向項(xiàng)目提交修改的權(quán)限,你也可以在線上建立你自己的代碼庫,將你自己的補(bǔ)丁發(fā)布出來,任何喜歡你補(bǔ)丁的人都可以將它們pull到他們自己的代碼庫中,當(dāng)然也包括項(xiàng)目維護(hù)人員.
Git有一個(gè)被稱為"staging area"的區(qū)域.在你向代碼庫提交之間, 你可以在這個(gè)中間區(qū)域中構(gòu)建你的提交.更為重要的是,你可以只提交部分的修改,而不是將所有修改的文件都進(jìn)行提交.你甚至可以只提交一個(gè)文件中修改的一部分.
Git非常的靈活,非常的TIMTOWTDI(There is more than one way to do it). 你可以使用任何你喜歡的工作流程,Git都會(huì)對(duì)其提供支持.
當(dāng)前主要的工作流程有以下幾種:
1. SVN形式
集中式的工作流程,這也是一種非常普遍的Git的工作流程.如果在你上一次fetch代碼之后有其他人進(jìn)行了提交,那么Git將不允許你向主代碼庫中push你的代碼.
2. 集成管理形式
在這個(gè)工作流程中有一個(gè)集成管理人員,他向"blessed"代碼庫進(jìn)行提交,其他開發(fā)人員從這個(gè)代碼庫clone代碼,在他們自己的代碼庫中push修改,并讓集成管理人員pull他們的修改.這其實(shí)就是大多數(shù)開源項(xiàng)目和GitHub所經(jīng)常使用的開發(fā)模式.
3. 獨(dú)裁者和中尉形式
對(duì)于更大規(guī)模的項(xiàng)目來說,你可以將開發(fā)人員的開發(fā)模式設(shè)置成類似于Linux內(nèi)核的開發(fā)模式.某些人會(huì)負(fù)責(zé)項(xiàng)目的某個(gè)特定的子系統(tǒng)(中尉),并且將所有關(guān)于這個(gè)子系統(tǒng)的修改都進(jìn)行合并.另外會(huì)有一個(gè)集成者(獨(dú)裁者)可能從他/她的中尉那里pull代碼的修改,并將"blessed"代碼庫進(jìn)行提交.而所有人都可以從"blessed"代碼庫進(jìn)行代碼的拷貝.
再次強(qiáng)調(diào),Git對(duì)于工作流程的支持非常的靈活,你可以根據(jù)自己的需要來匹配,混合,選擇這些工作流程.
我們再來看看相對(duì)于SVN,Git還有哪些優(yōu)點(diǎn)吧:
據(jù)說目前Git不支持代碼庫的部分checkout/clone,但是正在開發(fā)中,而且已經(jīng)有submodule方面的支持.SVN則可以根據(jù)需要只從代碼庫中checkout某個(gè)子文件夾.SVN的版本號(hào)更短并且可以預(yù)知,而Git的版本號(hào)則是40位的16進(jìn)制數(shù)字串.而Git在Branch方面的處理應(yīng)該是有很大的優(yōu)勢,但是由于我目前為止幾乎沒有使用過branch,所以這一部分還沒有深刻的體會(huì).
轉(zhuǎn)自:http://www.uml.org.cn/pzgl/201207264.asp
總結(jié)
以上是生活随笔為你收集整理的分布式和集中式版本控制工具-svn,git,mercurial比较分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国农业大学2020计算机院线,2020
- 下一篇: 【工具推荐】在线latex公式编辑器(可