分布式版本控制軟件水銀(Mercurial)使用指南0

Subversion Re-education

翻譯自:http://hginit.com/00.html

當我們公司的程序員決定將版本控制工具從SVN轉為水銀時,我很迷惑。

我首先想到的是所有不能換工具的理由。“我們必須要有一個中心倉庫,那樣才安全,”我說。然而我錯了。在水銀中,每個開發人員的硬盤中都存有倉庫的一份拷貝,那樣才真的是安全。況且幾乎每個用水銀管理的團隊都用了中心倉庫。

“分布式版本控制的麻煩在于它制造了太多的分支,”我說,“而分支往往帶來麻煩。”結果,這個想法又錯了。連續挫敗。分支在SVN上造成問題是因為SVN沒有存儲足夠的信息來進行合并操作。在水銀中,合并不會帶來任何損失且很容易,因此分支是常用而無害的東西。

最后我說:“好吧,我會用它的,但是別指望我弄懂它。”然后我讓Jacob幫我弄一張小抄,列出所有SVN常用操作在水銀上的替代。

現在,我可以給你展示一下這張小抄,但我想還是算了。因為它把我的腦子搞壞了幾個月。

如果你一直是用SVN的,那說好聽點,你會腦殘。不好意思,這似乎并不好聽。你需要來點再教育。我腦殘了6個月,在這6個月中,我覺得水銀比SVN復雜多了。而現在想起來,都是因為我沒有理解其精髓。而一旦我了解到了,水銀就變得異常簡單。

所以我為你寫下這份教程。我小心翼翼地繞開SVN來解釋這個系統,因為我不想你也像我一樣腦子灌水。因為這個世界已經夠二了。對于那些也是從SVN轉來的朋友。我寫這一章的目的就是為了試著替你清洗腦傷以使得你可以如一張白紙般學習水銀。

如果你完全沒有使用過SVN,那么你可以直接跳到下一章而不會錯過任何事。

準備好了嗎?OK,讓我們以一個簡短的測試開始。

問題1. 你會一次就寫出完美的代碼嗎?

如果你的回答是“是的”,那么你是一個騙子一個作弊生。你的測試沒有通過。重新測試吧。

新的代碼總是會有問題。需要花些時間花些努力才能讓它較好地運行。而在這之前,你的代碼可能會給同一團隊的其他開發者造成困擾。

下面SVN的方式:

  • 當你把你的新代碼check in,所有其他人都得到了它。

由于你寫的新代碼會有問題,因此你有兩個選擇。

  • 你可以check in有問題的代碼并讓所有人都抓狂,或者
  • 你可以知道它完全沒有問題了再check in。

SVN往往給你這樣的可怕困境。要么倉庫中由于新代碼的提交充滿了各種bug,要么新代碼沒辦法放到倉庫里面去。

作為SVN的使用者,我們是如此習慣于這樣的困境以致于基本不會去想象沒有這個困境的樣子。

SVN的團隊經常數日或數周都不check in任何東西。在SVN的團隊中,新手更是不敢check in任何東西,因為害怕破壞構建,或者害怕被上司罵。Mike有一次非常生氣,因為有一次checkin破壞了整體的構建。他沖到實習生的隔間,把他桌子上的東西推落一地,然后咆哮道:“這是你的最后一天了!”(當然沒有成為實習生的最后一天,但是那個可憐的實習生顯然哭了鼻子。)

這所有的恐懼導致人們幾周幾周地不敢使用版本控制工具來控制自己的版本,然后再找個高手幫助他們把代碼check in。如果你沒辦法用版本控制工具,你又為何使用它?

下圖是SVN生活下的簡單示例。

圖一

在水銀中,每個開發者在他們的電腦中都有它們自己的倉庫:

圖二

這樣,你就可以把代碼提交到你的私人倉庫,并且享受版本控制帶來的好處。每當你到達了一個代碼好了一點點的邏輯點,你就可以提交你的代碼。

一旦你的版本變的穩固了,并且希望別人也能使用你的新代碼時,你就可以把你的變更從你的倉庫推送到中央倉庫。這樣,別人就都可以通過拉取來看到你的代碼了。

水銀將提交新代碼的操作與影響其他人的操作分離了。

這就意味著你可以在其他人不知情的前提下提交(hg com)。當你已經有了一堆變更,并且你覺得已經穩定了且希望給別人看時,你可以推送(hg push)它們到主倉庫中。

一個更大的概念上的差別

你知道如何給每條街命名嗎?

在日本,他們往往只是在街與街之間用數字標明街區。只有非常非常重要的街才會有名字。

圖三

SVN與水銀的差別有些類似。

SVN喜歡考慮版次。一個版次是說在某個特定的時間點,整個文件系統看起來是什么樣的。

在水銀中,考慮的是變更集。一個變更集是兩個版次間的差異列表。

半斤與八兩:區別在哪里?

區別在這里。想象一下你和我都在一段代碼上進行工作,并且我們對那段代碼進行了分支。我們分別在這段代碼上做了很多工作,也改變了很多,所以它們越走越遠了。

當我們想要合并時,SVN試著去看兩個版本——我改的代碼,和你改的代碼——它嘗試著去猜測如何把他們打碎拼裝成一個大塊。它往往會失敗,產生整頁整頁的“合并沖突”。而它們往往不是真的沖突,而是SVN無法認出我們干了什么。

另一方面,當我們各自在水銀工作,水銀做的是保持一系列的變更集。因此,當我們想要合并我們的代碼時,水銀有更多的信息:它知道我們各自改了什么,并且可以重新應用這些變更,而非只是看看最終的結果,并看看如何把它倆放到一起。

例如,如果我對某個函數更改了一點,然后把它移到別的地方去了。SVN并不記住這些步驟,所以當要做合并時,它可能會認為一個新的函數產生了。而水銀記住了這些變更:函數改變了,函數移動了。這以為著,如果你也改變了函數一點點。那么水銀很可能會成功地合并我們的變更。

既然水銀考慮的是變更集,那么你就可以對那些變更集做些有趣的事情。你可以把變更集推送給你的隊友進行嘗試,而不是放到中心倉庫去影響所有的人。

如果這些看著有些暈,不要著急——當你完成了所有教程,你會完全明白。現在你要知道的最重要的事情就是:由于水銀是考慮的“變更集”而不是“版次”,因此可以比SVN合并地更好。

這就以為著你可以隨意分支。因為合并不再是一個噩夢。

想知道些有趣的事嗎?幾乎所有的SVN團隊都會給我講同一個故事的不同變種。這個故事是那么地普遍以致于我想叫它“SVN故事#1”。故事是這樣說的:在某個時間點,他們試圖對代碼進行分支,通常是為了把交付給客戶的版本與開發版本相剝離。所有的團隊都說,當他們這么做時,沒有問題。直到他們希望合并時,這成了噩夢。如果合并操作只需要五分鐘,而不是整個團隊圍繞一臺電腦奮戰2周,會是怎么樣的一種體驗?

幾乎每個SVN的團隊告訴我他們發誓不要再發生這樣的事情,并且不再使用分支。現在他們這么做:每個新特征都在一個大的#ifdef的代碼塊中。這樣,他們就可以工作在一個樹干中。客戶不會看到新代碼,除非是在調試過程中。坦白地說,這很荒唐。

分開保存穩定版代碼和開發版代碼應當是源代碼控制幫助你做的事情。

當你轉而使用水銀,你可能還沒有意識到,但分支變的可用,而且你不需要害怕。

這意味著你可以有一個團隊倉庫,小團隊的成員協作完成一個新特性。當他們完成時,他們把工作合并到開發倉庫中。然后事情就成了。

這意味著你可以在獨立的倉庫進行實驗,如果它們成功了,你可以合并到主倉庫中,如果失敗了,就可以直接刪除!

最后一個概念上的區別

最后一個主要的SVN和水銀的差別并不是什么大事,但是如果你不注意的話會讓你出差錯,這就是:

SVN是對文件的版本控制。但是在水銀中,版本控制總是應用于整個文件夾——包括所有的子目錄。

你注意到這個的方式是,在SVN中,如果你進入一個子目錄并且提交你的變更,它僅僅提交那個子目錄以下的變更,這潛在地意味著你忘了把其它子目錄里面的變更checkin了。然而,在水銀中,所有的命令都應用在整個目錄結構中。如果你的代碼在c:\code,則當你執行hg commit命令,你的工作目錄可以在c:\code或者在其中的任何一個子文件夾中。效果是一樣的。

這不是一個大問題,但是如果你習慣于讓全公司擁有一個巨大的倉庫——人們只check out出他們關心的子目錄,并且在上面工作,則水銀不是一種好的方式——你最好是構建為不同的項目構建很多小的倉庫。

最后……

這一部分,我希望你直接相信我。

水銀比SVN好。

它是一個團隊共同在源代碼上工作的更好的方式。它是你自己在源代碼上工作的更好方式。

它就是更好。

記住我的話,如果你理解水銀的工作方式,如果你用水銀的方式工作,如果你不去斗爭,不去試著用SVN的方式使用水銀而是學習水銀希望你工作的那種方式。你會變得快樂,成功,滿足,而且總能找到電視的遙控器。

早期,你會被誘惑,離開水銀重投SVN的懷抱。因為水銀對你來說很陌生,你就像生活在異國他鄉。你會想家,并提出很多回家的理由,譬如,你會抱怨水銀的工作目錄太占空間了,然而實際上,它們比SVN占的空間要小。(這是真的!)

然后你想回到SVN的懷抱因為你嘗試著用SVN的方式去分支,然而你迷惑了,它并不能工作。因為你真的需要用水銀的方式分支——通過拷貝倉庫的方式——而不是SVN的方式。相信我,這會工作地很好。

之后你會遇到Jacob,或者在你的辦公室相當于Jacob的那個人,給你一張“SVN到水銀的轉換小抄”,然后你會在三個月的時間內認為hg fetch就像svn up,而并不真正了解hg fetch在干嗎。當有一天,事情變糟了。你會怪罪水銀。但其實你應該怪罪的是你自己沒有理解水銀工作的方式。

我知道你會做那些因為我自己曾經做過。

不要犯同樣的錯誤。學習水銀,相信水銀,用水銀的方式來干活,之后你會在版本控制的思維上有大的進步。當供應商更新了一個庫,你的競爭者在花一周時間解決所有的合并問題;而你只是輸入了hg merge,然后告訴你自己,“天吶,太酷了,成了!”

FAQ

Q:分布式版本控制不安全,因為svn有一個中央倉庫,那樣更安全。

A:分布式版本控制使得每個人那里都有一個備份,而且一般都會配置一個中心倉庫。你說哪個更安全?

Q:分布式版本控制太容易造成分支了,而分支往往會帶來問題。

A:那是因為SVN沒有存儲足夠的信息來進行分支間的合并。而水銀的分支間合并已經做的很好了,根本無害。不要因為SVN做的不好,就說分支本身不好!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容