第一章 版本控制簡史

第一章 版本控制簡史

1.1 為什么要進(jìn)行版本控制夹囚?為什么選擇Mercurial苹丸?

版本控制是管理一段信息的多個(gè)版本的過程。在最簡單的情形中课梳,就像許多人手工所做的:每當(dāng)修改一個(gè)文件理卑,就將其保存在一個(gè)包含數(shù)字的新文件名之下翘紊,每個(gè)數(shù)字都會(huì)高于前一個(gè)版本的數(shù)字。

即使是單個(gè)文件藐唠,手動(dòng)管理其多個(gè)版本仍然是一項(xiàng)極易出錯(cuò)的任務(wù)帆疟,因此,自動(dòng)化這一過程的軟件工具早已出現(xiàn)宇立。最早的自動(dòng)版本控制工具旨在幫助單個(gè)用戶管理單個(gè)文件的各個(gè)版本踪宠。在過去幾十年,版本控制工具的范圍擴(kuò)大了很多÷栲冢現(xiàn)在柳琢,它們可以管理許多文件,并幫助許多人一起工作润脸。最好的現(xiàn)代版本控制工具應(yīng)對(duì)成千上萬的人在包含成千上萬個(gè)文件的項(xiàng)目上一起工作一點(diǎn)問題都沒有柬脸。

分布式版本控制是最近才出現(xiàn)的,由于人們樂于探索未知領(lǐng)域毙驯,到目前為止這個(gè)嶄新的領(lǐng)域仍在發(fā)展倒堕。

因?yàn)槲蚁嘈欧植际桨姹究刂剖且粋€(gè)重要的主題,需要一本專業(yè)的指導(dǎo)尔苦,因此我要寫一本關(guān)于它的書籍。最終選擇寫一本關(guān)于Mercurial的書籍,是因?yàn)樗菍W(xué)習(xí)該領(lǐng)域知識(shí)最簡單的工具允坚,同時(shí)可以應(yīng)用到到其它版本控制工具無法承擔(dān)的真實(shí)的魂那、挑戰(zhàn)性的需求環(huán)境中。

1.1.1 為什么要進(jìn)行版本控制稠项?

你的項(xiàng)目團(tuán)隊(duì)為什么需要一個(gè)自動(dòng)化的版本控制工具涯雅?有以下幾個(gè)理由:

  • 它將跟蹤項(xiàng)目的歷史和演變,所以你不必親為展运。對(duì)于項(xiàng)目的每個(gè)變化活逆,都會(huì)有一個(gè)日志來記錄誰做的修改,為什么修改拗胜,什么時(shí)候進(jìn)行的修改蔗候,修改了些什么。

  • 當(dāng)你與其他人合作時(shí)埂软,版本控制軟件使你們更便于協(xié)作锈遥。例如,當(dāng)人們或多或少同時(shí)進(jìn)行可能不兼容的更改時(shí)勘畔,軟件將幫助你識(shí)別和解決這些沖突所灸。

  • 它可以幫助你從錯(cuò)誤中恢復(fù)。如果您進(jìn)行的更改后來證明是錯(cuò)誤的炫七,您可以將一個(gè)或多個(gè)個(gè)文件還原到一個(gè)早期的版本爬立。事實(shí)上,一個(gè)真正好的版本控制工具甚至可以幫助你有效地確定問題是何時(shí)引入的(詳見“找出錯(cuò)誤的源頭”)万哪。

  • 可以讓你并行地工作侠驯,并管理你在項(xiàng)目中多個(gè)版本之間的跳轉(zhuǎn)。

一個(gè)項(xiàng)目壤圃,無論只有你一個(gè)人陵霉,還是還有幾百個(gè)別人,這些理由中的大部分都成立——至少在理論上伍绳。

在兩種不同規(guī)模的項(xiàng)目(“個(gè)人”和的“大型團(tuán)隊(duì)”)中踊挠,版本控制的可行性關(guān)鍵在于它的使用收益和使用開銷之比。一個(gè)難以理解和使用的版本控制工具必定會(huì)加大開銷冲杀。

對(duì)于一個(gè)五百人的項(xiàng)目效床,在沒有版本控制工具和方法的情況下,由于其自身的體量权谁,有可能會(huì)立即崩潰剩檀。這種情況下,版本控制的開銷幾乎可以忽略不計(jì)旺芽,因?yàn)闆]有它沪猴,項(xiàng)目注定會(huì)失敗辐啄。

另一方面,版本控制工具對(duì)于一個(gè)人的“快速上手”式開發(fā)看上去并不合適运嗜,因?yàn)槠湔嬲氖褂瞄_銷與項(xiàng)目的總體開銷相接近壶辜,是嗎?

Mercurial獨(dú)有地支持這兩種級(jí)別的開發(fā)担租。由于容易上手砸民,你可以非常輕松地在幾分鐘內(nèi)學(xué)會(huì)基本知識(shí),并在最小的項(xiàng)目中使用它來進(jìn)行版本控制奋救。它的簡單性意味著不會(huì)有很多深?yuàn)W的概念或命令序列需要你去掌握岭参,而只需專注于你真正想做的工作。同時(shí)尝艘,Mercurial的高性能和點(diǎn)對(duì)點(diǎn)的特性又可以讓您輕松的處理大型項(xiàng)目演侯。

任何版本控制工具都不能挽救一個(gè)糟糕的項(xiàng)目,但是利耍,選擇一個(gè)好的工具能夠?qū)?xiàng)目進(jìn)展是否順暢造成巨大的影響蚌本。

1.1.2 版本控制的許多名稱

版本控制用于許多領(lǐng)域,因此隘梨,它有許多稱呼和縮寫程癌。下面是一些最常見的說法:

  • 修訂控制系統(tǒng)(RCS)
  • 軟件配置管理(SCM),或配置管理
  • 源代碼管理
  • 源代碼控制或源控制
  • 版本控制系統(tǒng)(VCS)

有些人認(rèn)為這些術(shù)語實(shí)際上有不同的含義轴猎,但在實(shí)踐中它們有很大的重疊嵌莉,沒有一個(gè)約定甚至可用的方法來區(qū)分它們。

1.2 本書仍在完善中

本書發(fā)行的時(shí)候仍處于編寫之中捻脖,希望它對(duì)別人有用锐峭。我在一個(gè)開放的許可下編寫了該書,希望你可婶,我的讀者沿癞,能夠提供反饋,也包括你自己的內(nèi)容矛渴。

1.3 關(guān)于本書的示例

本書對(duì)代碼示例采用了一種不常見的方法椎扬。每個(gè)示例都是“真實(shí)”的——每個(gè)示例實(shí)際上都是 shell腳本的運(yùn)行結(jié)果,這個(gè)腳本包含了你見到的Mercurial命令具温。每當(dāng)從源文件構(gòu)建本書的映像時(shí)蚕涤,所有示例腳本都會(huì)自動(dòng)運(yùn)行,并將其輸出結(jié)果與預(yù)期結(jié)果進(jìn)行比較铣猩。

這種方法的優(yōu)點(diǎn)是示例總是準(zhǔn)確的揖铜。這些示例完全精確的給出了本書前面所提及的特定版本 Mercurial的行為。如果更新了該書所用的Mercurial的版本达皿,一些命令的輸出就會(huì)改變天吓,構(gòu)建也會(huì)失敗贿肩。

這種方法有一個(gè)小的缺點(diǎn),就是你在例子中所看到的日期和時(shí)間往往被“擠壓”在一起龄寞,如果相同的命令是由一個(gè)人從鍵盤輸入的尸曼,就不會(huì)這個(gè)樣子。自動(dòng)示例腳本每秒鐘會(huì)執(zhí)行許多命令萄焦,而一個(gè)人每隔幾秒才會(huì)發(fā)出一個(gè)命令,從而每個(gè)執(zhí)行結(jié)果所對(duì)應(yīng)的輸出時(shí)間會(huì)被拉開冤竹。

舉個(gè)這樣的例子拂封,示例中幾個(gè)連續(xù)提交都顯示是在同一秒內(nèi)發(fā)生的。你可以在137頁“找出錯(cuò)誤的源頭”中的二分法示例部分發(fā)現(xiàn)這種情況鹦蠕。

所以冒签,當(dāng)你閱讀示例時(shí),不要過分關(guān)注命令輸出中的日期或時(shí)間钟病。但要相信你看到的行為是一致的和可重現(xiàn)的萧恕。

1.4 該領(lǐng)域的未來趨勢

在過去四十年里,在開發(fā)和使用版本控制工具方面有一個(gè)明確的趨勢肠阱,因?yàn)槿藗円呀?jīng)熟悉了這些工具的能力并受限與它的局限票唆。

第一代工具只能在單臺(tái)計(jì)算機(jī)上管理單個(gè)文件。雖然這些工具相比手動(dòng)版本控制是一個(gè)巨大的進(jìn)步屹徘,但鎖定模型和對(duì)單一計(jì)算機(jī)的依賴使得它們只能用于小型和緊湊的團(tuán)隊(duì)走趋。

第二代工具采用了以網(wǎng)絡(luò)為中心的架構(gòu),并且同時(shí)可以管理整個(gè)項(xiàng)目噪伊,從來突破了這些限制簿煌。隨著項(xiàng)目越來越大,它們遇到了新的問題鉴吹。由于客戶端需要與服務(wù)器頻繁地通信姨伟,對(duì)于大型項(xiàng)目,服務(wù)器的規(guī)模成了問題豆励。不可靠的網(wǎng)絡(luò)連接可能會(huì)導(dǎo)致遠(yuǎn)程用戶根本無法與服務(wù)器進(jìn)行通信夺荒。開源項(xiàng)目允許任何人匿名訪問,但只有讀取權(quán)限肆糕,這些沒有提交權(quán)限的用戶無法記錄他們所做的修改般堆,從而使用這些工具不能與項(xiàng)目進(jìn)行正常的交互。

當(dāng)前的版本控制工具本質(zhì)上是點(diǎn)對(duì)點(diǎn)的诚啃。它們都降低了對(duì)單個(gè)中央服務(wù)器的依賴淮摔,并允許人們將其版本控制數(shù)據(jù)發(fā)布到實(shí)際需要的地方。通過互聯(lián)網(wǎng)協(xié)同工作已經(jīng)從技術(shù)上的限制轉(zhuǎn)變?yōu)闆Q策和看法上的問題∈际辏現(xiàn)代的工具已經(jīng)可以長久地在離線狀態(tài)下自主運(yùn)作和橙,只有在想將更改同步到另一個(gè)存儲(chǔ)庫時(shí)才需要網(wǎng)絡(luò)連接仔燕。

1.5 分布式版本控制工具的優(yōu)勢

幾年來,盡管分布式版本控制工具已經(jīng)同其上一代的同類產(chǎn)品一樣穩(wěn)健可用魔招,但使用舊工具的人們還是不一定能夠認(rèn)識(shí)到它們的優(yōu)點(diǎn)晰搀。相對(duì)于集中式工具,分布式工具有許多亮點(diǎn)办斑。

對(duì)于單個(gè)開發(fā)人員外恕,分布式工具幾乎總是比集中式工具快得多。原因很簡單:對(duì)于集中式工具乡翅,許多常見操作需要通過網(wǎng)絡(luò)進(jìn)行鳞疲,因?yàn)榇蠖鄶?shù)元數(shù)據(jù)只是在中央服務(wù)器上保存了一份。分布式工具在本機(jī)保存所有元數(shù)據(jù)蠕蚜。其它都是一樣的尚洽。網(wǎng)絡(luò)通訊導(dǎo)致了集中式工具額外的開銷。不要低估一個(gè)快速響應(yīng)工具的價(jià)值:你將花費(fèi)大量的時(shí)間與你的版本控制軟件進(jìn)行交互靶累。

分布式工具不受服務(wù)器基礎(chǔ)結(jié)構(gòu)變化的影響腺毫,原因同樣是因?yàn)樗鼈儗⒃獢?shù)據(jù)復(fù)制到許多地方。如果你使用集中式系統(tǒng)挣柬,并且服務(wù)器發(fā)生了故障潮酒,你最好期望你的備份介質(zhì)是可靠的,你上次的備份是最新的邪蛔,并且真的可以恢復(fù)澈灼。對(duì)于分布式工具,可以從每個(gè)貢獻(xiàn)者的計(jì)算機(jī)上獲取許多備份店溢。

網(wǎng)絡(luò)可靠性對(duì)分布式工具的影響遠(yuǎn)小于對(duì)集中式工具的影響叁熔。沒有網(wǎng)絡(luò)連接,您甚至不能使用集中式工具床牧,除非極有限的幾個(gè)命令荣回。對(duì)于分布式工具,如果網(wǎng)絡(luò)在你工作時(shí)斷開戈咳,你甚至不會(huì)注意到心软。唯一不能做的是與其它計(jì)算機(jī)上的存儲(chǔ)庫相通訊,與本地操作相比這是相對(duì)少見的著蛙。如果你的團(tuán)隊(duì)合作者之間相距遙遠(yuǎn)删铃,這一點(diǎn)可能很重要。

1.5.1 對(duì)開源項(xiàng)目的好處

如果你喜歡一個(gè)開源項(xiàng)目踏堡,并決定改進(jìn)它猎唁,而且這個(gè)項(xiàng)目使用了分布式版本控制工具,那么你與那些自認(rèn)為是項(xiàng)目“核心”成員的人是平等的顷蟆。如果他們發(fā)布了自己的存儲(chǔ)庫诫隅,你就可以作為他們中的一員腐魂,使用相同的工具和同樣的方法,立即復(fù)制他們項(xiàng)目的歷史記錄逐纬,開始進(jìn)行更改蛔屹,并記錄你的工作。相比之下豁生,對(duì)于集中式工具兔毒,你必須以“只讀”模式使用它,除非有人授予你向中央服務(wù)器提交變更的權(quán)限甸箱。在此之前眼刃,你無法記錄變更,并且當(dāng)你嘗試更新客戶端的存儲(chǔ)庫視圖時(shí)摇肌,你的本地修改將面臨損壞的風(fēng)險(xiǎn)。

分支不是問題

有人認(rèn)為分布式版本控制工具會(huì)對(duì)開源項(xiàng)目構(gòu)成某種風(fēng)險(xiǎn)仪际,因?yàn)樗鼈內(nèi)菀自斐身?xiàng)目開發(fā)的“分支”围小。當(dāng)開發(fā)組內(nèi)部成員之間的意見或態(tài)度存在差異,而決定不再一起工作時(shí)树碱,分支就會(huì)發(fā)生肯适。每一方都會(huì)有一個(gè)多少完整的項(xiàng)目源代碼副本,并沿著自己的方繼續(xù)成榜。

有時(shí)框舔,分支的各個(gè)陣營決定協(xié)調(diào)分歧。使用集中式版本控制系統(tǒng)赎婚,和解的技術(shù)歷程是痛苦的刘绣,大部分工作必須手動(dòng)完成。你必須決定誰的版本歷史“獲勝”挣输,然后以某種方式將其它團(tuán)隊(duì)的修改移植到該版本樹纬凤。這樣通常會(huì)丟失其中一方的部分或全部版本歷史。

在分支方面撩嚼,分布式工具認(rèn)為分支是項(xiàng)目開發(fā)的唯一方法停士。你所做的每一個(gè)改變都是一個(gè)潛在的分支點(diǎn)。這種提法的堅(jiān)實(shí)基礎(chǔ)是分布式版本控制工具必須真正善于合并分支完丽,因?yàn)榉种墙^對(duì)根本:它們總在發(fā)生恋技。

假如每個(gè)人所做的每一件工作,都是以分支和合并的方式構(gòu)成的逻族,那么開源世界所謂的“分支”純粹是一個(gè)社會(huì)問題蜻底。如果有的話,分布式工具降低了分支的可能性:

  • 它們消除了集中式工具強(qiáng)加的社會(huì)差異:該差異存在于內(nèi)部人員(具有提交權(quán)限的人員)和外部人員(無提交權(quán)限的人員)之間聘鳞。

  • 它們使得分支之后的協(xié)調(diào)更加容易朱躺,因?yàn)閺陌姹究刂栖浖慕嵌瓤吹罄担恍枰賮硪淮魏喜⒍选?/p>

有些人抵制分布式工具,因?yàn)樗麄兿M麑?duì)其項(xiàng)目保持嚴(yán)格的控制长搀,并認(rèn)為集中式工具可以提供這種控制宇弛。然而,如果你有這個(gè)想法源请,并且公開了你的CVS或Subversion存儲(chǔ)庫枪芒,就有很多工具可以提取整個(gè)項(xiàng)目歷史(雖然緩慢),并在你不能控制的地方重建它谁尸。所以舅踪,在這種情況下,你的控制是虛幻的良蛮,你正在放棄與別人協(xié)作的機(jī)會(huì)抽碌,逼迫他們鏡像你的項(xiàng)目歷史并創(chuàng)建分支。

1.5.2 對(duì)商業(yè)項(xiàng)目的好處

許多商業(yè)項(xiàng)目是由分散在全球各地的團(tuán)隊(duì)負(fù)責(zé)的决瞳。遠(yuǎn)離中央服務(wù)器的貢獻(xiàn)者货徙,其命令的執(zhí)行會(huì)很慢,可靠性也可能較低皮胡。商業(yè)版本控制系統(tǒng)試圖通過遠(yuǎn)程站點(diǎn)復(fù)制附件來改善這些問題痴颊,這些附件通常很昂貴,并且難以管理屡贺。首先蠢棱,分布式系統(tǒng)不會(huì)遇到這些問題。更好的是甩栈,您可以輕松地設(shè)置多個(gè)權(quán)威服務(wù)器泻仙,例如每個(gè)站點(diǎn)一個(gè),以便在通過昂貴的長途網(wǎng)絡(luò)相連接的存儲(chǔ)庫之間沒有多余的通信量没。

集中式版本控制系統(tǒng)往往具有相對(duì)較低的可擴(kuò)展性饰豺。幾十個(gè)并發(fā)用戶的總負(fù)荷常常會(huì)導(dǎo)致一個(gè)昂貴的集中式系統(tǒng)倒下來。一個(gè)典型的應(yīng)對(duì)往往是采用昂貴和復(fù)雜的復(fù)制設(shè)施允蜈。因?yàn)槭褂梅植际焦ぞ叩闹醒敕?wù)器其負(fù)何——如果你有一個(gè)—— 要低很多倍(因?yàn)樗袛?shù)據(jù)被復(fù)制到各個(gè)地方)冤吨,單個(gè)廉價(jià)的服務(wù)器就可以滿足一個(gè)大型的團(tuán)隊(duì)的需要,一個(gè)簡單的腳本就可以進(jìn)行數(shù)據(jù)復(fù)制來平衡負(fù)載饶套。

如果您有一名某領(lǐng)域的員工漩蟆,正在客戶現(xiàn)場解決實(shí)際問題,他將受益于分布式版本控制妓蛮。這個(gè)工具可以讓他創(chuàng)建定制版本怠李,嘗試各種不同的修復(fù)方案,通過項(xiàng)目歷史高效地在客戶環(huán)境中進(jìn)行回溯并在源碼中定位缺陷。所有這些工作都不需要連接到公司的網(wǎng)絡(luò)捺癞。

1.6 為什么選擇Mercurial夷蚊?

Mercurial特有的屬性使其作為版本控制系統(tǒng)是一個(gè)非常好的選擇。

  • 易學(xué)易用髓介。
  • 輕量級(jí)惕鼓。
  • 卓越的伸縮性。
  • 易定制唐础。

如果你熟悉版本控制系統(tǒng)箱歧,應(yīng)該能夠在五分鐘之內(nèi)開始運(yùn)行Mercurial。即使不行一膨,也不會(huì)超過幾分鐘呀邢。Mercurial的命令和功能總體上是統(tǒng)一和連貫的,因此你只需要遵循幾個(gè)普遍的規(guī)則豹绪,而不用處理大量的例外价淌。

在一個(gè)小型項(xiàng)目中,你可以立即開始使用Mercurial瞒津。創(chuàng)建新的變更和分支蝉衣、傳輸變更(無論是本地還是通過網(wǎng)絡(luò))、獲取項(xiàng)目歷史和狀態(tài)仲智,這些操作都很快。Mercurial試圖通過將較低的門檻和快速的操作結(jié)合起來姻氨,以另一種方式來保持項(xiàng)目的敏捷钓辆。

Mercurial不僅能用于小型項(xiàng)目,對(duì)于那些擁有幾百甚至幾千個(gè)參與者肴焊,每個(gè)參與者包含數(shù)萬個(gè)文件前联,幾百兆源代碼的大型項(xiàng)目,它同樣適用娶眷。

如果Mercurial的核心功能對(duì)你來說不夠用似嗤,你也可以很容易的添加功能。Mercurial非常適合腳本化的任務(wù)届宠,它使用Python實(shí)現(xiàn)且內(nèi)部代碼清晰烁落,這使的它很容易使用擴(kuò)展來添加功能。目前豌注,從幫助標(biāo)識(shí)缺陷到提高性能等各個(gè)方面伤塌,已有許多流行且不錯(cuò)的擴(kuò)展可供使用。

1.7 比較Mercurial和其它工具

在閱讀之前轧铁,請(qǐng)理解每聪,這一部分必然摻雜有我的個(gè)人經(jīng)驗(yàn),興趣和(我敢說)偏見。我使用過下面列出的每一個(gè)版本控制工具药薯,通常都用過幾年绑洛。

1.7.1 Subversion

Subversion是一種流行的用于替換CVS的版本控制工具。它采用集中式客戶端/服務(wù)器架構(gòu)童本。
Subversion和Mercurial使用類似名稱的命令來執(zhí)行同樣的操作真屯,所以如果你熟悉其中之一,那么學(xué)習(xí)另一個(gè)也非常容易巾陕。這兩種工具都可以移植到所有流行的操作系統(tǒng)讨跟。

在版本1.5之前,Subversion不支持對(duì)合并進(jìn)行跟蹤鄙煤。在撰寫本書時(shí)晾匠,合并跟蹤功能剛剛添加,復(fù)雜且問題多多梯刚。

在我所做的基準(zhǔn)測試中凉馆,Mercurial相較于Subversion,每個(gè)版本控制操作都具有顯著的性能優(yōu)勢亡资。與Subversion 1.4.3最快的ra_local文件存儲(chǔ)方式相比澜共,這個(gè)優(yōu)勢在2到6倍之間。現(xiàn)實(shí)中的部署會(huì)涉及到網(wǎng)絡(luò)訪問锥腻,Subversion將更加處于劣勢地位嗦董。因?yàn)樵S多Subversion命令必須與服務(wù)器通信,而Subversion沒有有效的的復(fù)制工具瘦黑,所以對(duì)于大型項(xiàng)目京革,服務(wù)器容量和網(wǎng)絡(luò)帶寬將會(huì)成為主要瓶頸。

此外幸斥,對(duì)于一些常用操作匹摇,如找到已修改的文件(status)以及顯示文件相對(duì)于當(dāng)前版本所作的修改(diff),Subversion為了避免網(wǎng)絡(luò)傳輸甲葬,占用了大量的存儲(chǔ)空間廊勃。最終,盡管Mercurial存儲(chǔ)庫包含了完整的項(xiàng)目歷史经窖,Subversion工作副本仍然可以與Mercurial存儲(chǔ)庫及工作目錄具有相同的大小坡垫,甚至更大。

Subversion有大量的第三方工具支持画侣。目前葛虐,Mercurial在這方面相對(duì)滯后。然而棉钧,這種差距正在縮小屿脐,現(xiàn)在涕蚤,一些GUI工具,其Mercurial版甚至比Subversion版更加出色的诵。與Mercurial一樣万栅,Subversion有一個(gè)優(yōu)秀的用戶手冊(cè)。

因?yàn)镾ubversion不在客戶端存儲(chǔ)版本歷史西疤,所以它非常適合管理那些需要處理大量不可閱讀的二進(jìn)制文件的項(xiàng)目烦粒。對(duì)于一個(gè)10MB的不可壓縮文件,如果你撿出其50個(gè)版本代赁,Subversion的空間占用保持不變扰她。而對(duì)于任何分布式SCM,由于各個(gè)版本之間差異極大芭碍,所占用的空間會(huì)與檢出的版本數(shù)量成比例的快速增加徒役。

此外,通常很難甚至不可能合并不同版本的二進(jìn)制文件窖壕。Subversion能夠讓用戶鎖定一個(gè)文件忧勿,以便他們暫時(shí)擁有這個(gè)文件的獨(dú)占權(quán)限,并提交對(duì)其所作的修改瞻讽,對(duì)于一個(gè)廣泛使用二進(jìn)制文件的項(xiàng)目來說鸳吸,這是一個(gè)顯著的優(yōu)勢。

Mercurial能夠從Subversion存儲(chǔ)庫導(dǎo)入版本歷史速勇。也可以將版本歷史導(dǎo)出到Subversion存儲(chǔ)庫晌砾。這使得在確定從其中一個(gè)轉(zhuǎn)換到另一個(gè)之前,可以同時(shí)使用Subversion和Mercurial來“試水”烦磁。歷史記錄的轉(zhuǎn)換是增量式的养匈,因此你可以先執(zhí)行首次轉(zhuǎn)換,然后再執(zhí)行額外的小轉(zhuǎn)換个初,以引入新的文件變更乖寒。

1.7.2 Git

Git是一個(gè)分布式版本控制工具猴蹂,開發(fā)目的是用于管理Linux內(nèi)核源代碼樹院溺。與Mercurial一樣,它的早期設(shè)計(jì)有點(diǎn)受Monotone的影響磅轻。

Git有一個(gè)非常大的命令集珍逸,版本1.5.0提供了139個(gè)單獨(dú)的命令。它出了名的難學(xué)聋溜。與Git相比谆膳,Mercurial更注重簡潔。

在性能方面撮躁,Git非呈。快。至少在Linux下,多數(shù)情況要比Mercurial快杨帽,盡管個(gè)別操作Mercurial做得更好漓穿。但在Window下,到目前為止注盈,Git的性能和綜合支持級(jí)別仍遠(yuǎn)遠(yuǎn)落后于Mercurial晃危。
可是Mercurial存儲(chǔ)庫不需要維護(hù),而Git存儲(chǔ)庫需要頻繁地對(duì)其其元數(shù)據(jù)手動(dòng)“重新打包”老客。否則僚饭,性能就會(huì)下降,而空間占用則會(huì)快速增長胧砰。一個(gè)包含許多Git存儲(chǔ)庫的服務(wù)器鳍鸵,如果不經(jīng)常對(duì)它們重新打包,備份就會(huì)嚴(yán)重地受限于磁盤空間朴则,而且每天備份的時(shí)間會(huì)遠(yuǎn)遠(yuǎn)超過24小時(shí)权纤。與Mercurial存儲(chǔ)庫相比,一個(gè)剛剛打包過的Git存儲(chǔ)庫要稍小一些乌妒,但是一個(gè)未打包的存儲(chǔ)庫則要大上幾個(gè)數(shù)量級(jí)汹想。

Git內(nèi)核是使用C語言編寫的。許多Git命令是用shell或Perl腳本實(shí)現(xiàn)的撤蚊,這些腳本的品質(zhì)差別很大古掏。在腳本存在錯(cuò)誤的情況下盲目的運(yùn)行,結(jié)果往往是致命的侦啸。我已經(jīng)遇到過幾次這樣的情況槽唾。

Mercurial能夠從Git存儲(chǔ)庫導(dǎo)入版本歷史。

1.7.3 CVS

CVS可能是世界上使用最廣泛的版本控制工具光涂。由于其年代久遠(yuǎn)且內(nèi)部混亂庞萍,多年來它只進(jìn)行了少量的維護(hù)。

它使用了集中式客戶端/服務(wù)器架構(gòu)忘闻。它不會(huì)將相關(guān)聯(lián)的文件變動(dòng)組合成一個(gè)原子提交钝计,從而使人們很容易“破壞構(gòu)建”:一個(gè)人可以成功地提交一部分變動(dòng),剩余的變動(dòng)則由于需要合并而被阻止提交齐佳。這會(huì)導(dǎo)致其他人只能看到他工作成果的一部分私恬。這也會(huì)影響你對(duì)項(xiàng)目歷史記錄的使用。如果要查看某人對(duì)任務(wù)中某個(gè)部分所作的全部修改炼吴,則需要手動(dòng)檢查他對(duì)每個(gè)文件所做更改的描述和時(shí)間戳(如果你恰好知道這些文件有哪些)本鸣。

CVS的標(biāo)簽和分支概念很混亂,此處不再詳述硅蹦。它也不支持文件和目錄的重命名荣德,導(dǎo)致存儲(chǔ)庫非常容易被破壞闷煤。它幾乎沒有內(nèi)部的一致性檢查功能,因此涮瞻,甚至常常都不知道存儲(chǔ)庫是否已損壞曹傀,或者它是如何損壞的。對(duì)于任何項(xiàng)目都不推薦使用CVS饲宛,不論是現(xiàn)有的項(xiàng)目還是新啟動(dòng)的項(xiàng)目皆愉。

Mercurial可以導(dǎo)入CVS的版本歷史記錄。但是有些問題要注意艇抠,這些問題同樣存在于使用其它版本控制工具從CVS導(dǎo)入版本歷史幕庐。由于CVS缺乏對(duì)版本的原子提交,且文件系統(tǒng)的層次結(jié)構(gòu)沒有被版本化家淤,所以不可能完全精確地重建CVS歷史記錄异剥。有些工作像猜謎,重命名通常不會(huì)顯示絮重。因?yàn)楹芏喔呒?jí)CVS管理必須手工完成冤寿,所以容易出錯(cuò),從CVS導(dǎo)入時(shí)常常就會(huì)發(fā)生多種存儲(chǔ)庫損壞問題(我個(gè)人只經(jīng)歷過兩個(gè)不太有趣的問題青伤,完全錯(cuò)誤的版本時(shí)間戳和文件被鎖定超過十年)督怜。

Mercurial能夠從CVS存儲(chǔ)庫導(dǎo)入版本歷史。

1.7.4 商業(yè)工具

Perforce具有集中式的客戶端/服務(wù)器架構(gòu)狠角,客戶端沒有任何數(shù)據(jù)緩存号杠。與現(xiàn)代的版本控制工具不同,Perforce需要用戶為每個(gè)準(zhǔn)備編輯的文件運(yùn)行一個(gè)命令來通知服務(wù)器丰歌。
Perforce的性能對(duì)小型團(tuán)隊(duì)來說相當(dāng)不錯(cuò)姨蟋,但隨著用戶數(shù)量增長到超過幾十個(gè),Perforce的性能迅速下降立帖。安裝較大的Perforce需要部署代理來應(yīng)對(duì)用戶負(fù)載眼溶。

1.7.5 選擇版本控制工具

除了CVS之外,上面列出的所有工具都有其獨(dú)特的優(yōu)勢來適應(yīng)特定的工作方式晓勇。沒有一個(gè)版本控制工具在所有情況下都是最好的堂飞。

例如,對(duì)于頻繁編輯二進(jìn)制文件的工作宵蕉,Subversion是一個(gè)好選擇酝静,因?yàn)樗鼘?shí)質(zhì)上是集中式的且支持對(duì)文件加鎖节榜。

我個(gè)人認(rèn)為羡玛,Mercurial 擁有簡單,高性能和良好的合并支持宗苍,并成功地將這些特性組合了起來稼稿,我已經(jīng)使用它好幾年了薄榛。

1.8 從其它工具切換至Mercurial

Mercurial捆綁了一個(gè)叫做convert的擴(kuò)展,它可以從其它的幾個(gè)版本控制工具中增量式導(dǎo)入版本歷史让歼〕担“增量”的意思是,到目前為止項(xiàng)目的所有歷史可以被一次性轉(zhuǎn)換谋右,隨后可以重新運(yùn)行轉(zhuǎn)換以獲得初次轉(zhuǎn)換之后新發(fā)生的變更硬猫。

擴(kuò)展convert支持以下版本控制工具:

  • Subversion
  • CVS
  • Git
  • Darcs

此外,convert可以將版本從Mercurial導(dǎo)出到Subversion改执。這使得在確認(rèn)轉(zhuǎn)換到Mercurial之前啸蜜,可以嘗試同時(shí)使用Subversion和Mercurial,從而不會(huì)有丟失任何已完成工作的風(fēng)險(xiǎn)辈挂。

convert命令很容易使用衬横,只需指定源存儲(chǔ)庫的路徑或URL,可選地终蒂,也可以指定目標(biāo)存儲(chǔ)庫的名稱蜂林,這樣就可以工作了。首次轉(zhuǎn)換之后拇泣,只需再次運(yùn)行相同的命令即可導(dǎo)入新的變更噪叙。

1.9 版本控制簡史

早期最著名的版本控制工具是Marc Rochkind在20世紀(jì)70年代初在貝爾實(shí)驗(yàn)室編寫的SCCS(源代碼控制系統(tǒng))。SCCS對(duì)單個(gè)文件進(jìn)行操作霉翔,并且要求項(xiàng)目中的每個(gè)人都可以存取單個(gè)系統(tǒng)上的共享工作空間构眯。任何時(shí)候只有一個(gè)人可以修改文件,并通過對(duì)文件加鎖來解決訪問沖突早龟。鎖定文件后忘記解鎖的事情經(jīng)常發(fā)生惫霸,導(dǎo)致其他人無法修改這些文件,除非請(qǐng)求管理員的幫助葱弟。

在80年代初壹店,Walter Tichy針對(duì)SCCS開發(fā)了一種免費(fèi)的替代方案,叫做RCS(修訂控制系統(tǒng))芝加。與SCCS一樣硅卢,RCS需要開發(fā)人員在單個(gè)共享工作空間中工作,并且鎖定文件以防止多個(gè)人同時(shí)修改它們藏杖。

在80年代后期将塑,Dick Grune使用RCS作為基礎(chǔ)創(chuàng)建了一組shell腳本,最初叫做cmt蝌麸,但后來又改名為CVS(并行版本系統(tǒng))点寥。CVS的重大創(chuàng)新是它讓開發(fā)人員在自己的個(gè)人工作空間中同時(shí)并相對(duì)獨(dú)立地工作。而SCCS和RCS中常見的情況来吩,就是個(gè)人工作空間始終阻礙著開發(fā)者前進(jìn)的步伐敢辩。CVS項(xiàng)目中蔽莱,每個(gè)開發(fā)人員都有項(xiàng)目中所有文件的副本,并且可以獨(dú)立地修改這些副本戚长。在將變更提交到中央存儲(chǔ)庫之前他們必須合并其修改盗冷。

Brian Berliner用C語言重寫了Grune的原始腳本,并于1989年發(fā)布同廉,自此仪糖,這些代碼逐漸發(fā)展成為了現(xiàn)代版本的CVS。后來迫肖,CVS擁有了通過網(wǎng)絡(luò)連接進(jìn)行操作的能力乓诽,它使用了客戶端/服務(wù)器架構(gòu)。CVS的架構(gòu)是集中式的咒程,只有服務(wù)器擁有項(xiàng)目的歷史記錄鸠天。客戶端工作空間只包含項(xiàng)目文件最新版本的副本帐姻,以及一些元數(shù)據(jù)來告訴他們服務(wù)器在哪里稠集。CVS取得了巨大的成功,它可能是世界上使用最廣泛的版本控制系統(tǒng)饥瓷。

在90年代初期剥纷,Sun Microsystems公司開發(fā)了一個(gè)早期的分布式版本控制系統(tǒng),稱為TeamWare呢铆。TeamWare的工作區(qū)包含完整的項(xiàng)目歷史晦鞋。TeamWare也沒有中央存儲(chǔ)庫的概念。(CVS依賴RCS保存歷史記錄棺克,而TeamWare使用SCCS悠垛。)

伴隨著90年代的步伐,人們逐漸地認(rèn)識(shí)到了CVS的一些問題娜谊。同時(shí)發(fā)生的修訂被分別地記錄到多個(gè)文件确买,而不是在邏輯上將它們組合在一起作為單個(gè)原子操作;不對(duì)文件的層次結(jié)構(gòu)進(jìn)行管理纱皆;很容易通過重命名文件和目錄使一個(gè)存儲(chǔ)庫變的混亂湾趾。更糟的是,它的源代碼很難閱讀和維護(hù)派草,這使得修復(fù)這些架構(gòu)問題令人望而卻步搀缠。

2001年,兩位原CVS的開發(fā)者Jim Blandy和Karl Fogel啟動(dòng)了一個(gè)新的項(xiàng)目近迁,使用更好的架構(gòu)和更簡潔的代碼來替換CVS艺普。結(jié)果就是Subversion,它延續(xù)了CVS的集中式客戶端/服務(wù)器架構(gòu),但添加了多文件原子提交衷敌,更好的命名空間管理,和許多其它功能拓瞪,使其成為一個(gè)比CVS更好的工具缴罗。因此它一經(jīng)發(fā)布,便迅速普及祭埂。

幾乎同時(shí)面氓,Graydon Hoare啟動(dòng)了一個(gè)雄心勃勃的分布式版本控制系統(tǒng)項(xiàng)目,稱之為Monotone蛆橡。雖然Monotone解決了許多CVS的設(shè)計(jì)缺陷舌界,并擁有一個(gè)點(diǎn)對(duì)點(diǎn)的架構(gòu),但相較早期(和后續(xù))的版本控制工具泰演,它的許多創(chuàng)新做法過于超前呻拌。它使用了加密的散列值作為標(biāo)識(shí)符,整體概念是“信任”來自不同來源的代碼睦焕。

Mercurial誕生于2005年藐握。雖然其設(shè)計(jì)受到Monotone多方面的影響,但Mercurial更專注于在大型項(xiàng)目上的易使用垃喊,高性能和可伸縮性猾普。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市本谜,隨后出現(xiàn)的幾起案子初家,更是在濱河造成了極大的恐慌,老刑警劉巖乌助,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溜在,死亡現(xiàn)場離奇詭異,居然都是意外死亡他托,警方通過查閱死者的電腦和手機(jī)炕泳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門虫埂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缴川,“玉大人土思,你說我怎么就攤上這事截粗±谜” “怎么了扒最?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵乾蓬,是天一觀的道長施戴。 經(jīng)常有香客問我纸俭,道長皇耗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任揍很,我火速辦了婚禮郎楼,結(jié)果婚禮上万伤,老公的妹妹穿的比我還像新娘。我一直安慰自己呜袁,他們只是感情好敌买,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阶界,像睡著了一般虹钮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上膘融,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天芙粱,我揣著相機(jī)與錄音,去河邊找鬼氧映。 笑死春畔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岛都。 我是一名探鬼主播拐迁,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疗绣!你這毒婦竟也來了线召?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤多矮,失蹤者是張志新(化名)和其女友劉穎缓淹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塔逃,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讯壶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了湾盗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伏蚊。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖格粪,靈堂內(nèi)的尸體忽然破棺而出躏吊,到底是詐尸還是另有隱情,我是刑警寧澤帐萎,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布比伏,位于F島的核電站,受9級(jí)特大地震影響疆导,放射性物質(zhì)發(fā)生泄漏赁项。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悠菜。 院中可真熱鬧舰攒,春花似錦、人聲如沸悔醋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篙顺。三九已至偶芍,卻和暖如春充择,著一層夾襖步出監(jiān)牢的瞬間德玫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國打工椎麦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宰僧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓观挎,卻偏偏與公主長得像琴儿,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嘁捷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • CVS : Git : Mercurial : Subversion 的異同特征 是否原子提交 CVS: 沒有. ...
    風(fēng)澈vio閱讀 2,731評(píng)論 0 62
  • 小組信息所在組名:天天向上本組組長:digman本組其他成員:豐盛姐 慧娟 夜影隨風(fēng)本組口號(hào):每天成長 每天學(xué)習(xí) ...
    digman閱讀 251評(píng)論 0 0
  • 我身邊有很多優(yōu)質(zhì)女生造成,長得漂亮,每天打扮的很精致雄嚣,性格又好晒屎,但都沒有男朋友。 難道真的是因?yàn)橐筇吡藛幔?朋友說...
    h寒暄一笑閱讀 340評(píng)論 0 2
  • I plan to cross-study these two topics. 1. Have you ever ...
    小_狐_貍閱讀 223評(píng)論 0 0
  • 看別人在追劇缓升、追星鼓鲁,而我最近在追一部小說。 追說的這一周里每晚都遲遲才肯入睡港谊,甚至有一個(gè)晚上熬到...
    鳳舞梧桐閱讀 290評(píng)論 0 1