Posted on 2011-06-27 20:17
幻海藍夢 閱讀(2131)
評論(0) 編輯 收藏 所屬分類:
Git
X | |
最近我花費了大量時間為 Gitsters 辯護以對抗那些 fanboyism, bandwagonism 以及 koolaid-thirst 的指責。 為此我建設了此網站來說明大家為什么要從 X 轉換至 Git,以及為何你也應該這么做。點擊任何一個原因展開以查看詳情。
hg bzr svn perforce
使 Git 從幾乎所有 SCM 中脫穎而出并出并且最吸引人的特色,恐怕非它的分支模型莫屬。 它完全不同于我在此用于比較的所有其他模型,那些模型所推薦的最佳分支方式僅僅是將庫 (repository) 復制到一個新的目錄而已。
Git 不那么做。 Git 允許你擁有多個完全獨立的本地分支,創建、合并和刪除這些分支僅需要幾秒鐘的時間。
這意味著你可以這樣做:
- 創建一個新分支嘗試新的想法,提交幾次,切換回原先的分支,應用一個 patch,然后再切換至剛才實驗中的新分支,將其合并。
- 一個分支用來存放將要發布的版本,另一個測試分支專門合并開發中的工作,其他數個小分支存放日常開發工作。
- 為每一個開發中的新功能建立相應分支,這樣便可以在這些分支中無縫切換,并在某個功能開發完畢合并進主分支后刪除相應分支。
- 創建一個分支來做實驗,若發現行不通則直接刪掉該分支;放棄這個分支,別人甚至不知道它存在過(即使這期間你已經 push 了其他分支)。
重要的是,當你向一個遠程庫 push 時,你無需 push 所有分支。你可以只共享一個分支而不是全部。 這會推動大家嘗試新想法而不用操心如何、何時合并或與他人共享。
使用其他系統,你也可以找到一些方法來做同樣的事,但會困難的多而且極易出錯。 Git 讓這個過程異常簡單,而且當大部分開發者學習 Git 時,他們同時改變了他們的工作方式。
svn perforce
雖然所有分布式 SCM 都有這特點,但根據我的經驗 Git 做的更好。除了 'fetch', 'pull' 和 'push', 你很少會用到其他需要跟你的硬盤以外的東西打交道的命令。
這不僅使大部分操作比你已經習慣的要快的多,而且讓你可以離線工作。 這聽起來不怎么樣,不過我經常為自己需要離線完成那么多工作感到驚訝。 當你在飛機或火車上還可以建立分支、合并、提交以及瀏覽項目歷史時,你的工作生產力會非常高。
即使是使用 Mercurial,諸如 'incoming' 和 'outgoing' 的常用命令也需要與服務器連接, 而 Git 讓你可以在離線前從服務器上 'fetch' 所有數據,然后對原本在你本地分支中并不存在的數據進行比較、合并或查看歷史紀錄。
這意味著可以很容易的在你的 Git 庫中同時保存你自己和與你協同工作的其他人的多個分支,而不會弄混任何內容。
bzr svn perforce
Git 很快。 包括大部分其他系統的忠實用戶在內的人都這么評價 Git。 Git 所有操作都在本地進行的特性使它比 SVN 和 Perforce 要快,因為后兩者的普通操作都要進行網絡連接。 即使與其他允許本地操作的分布式 SCM 相比,Git 也要快得多。
部分原因可能是因為 Git 是被創造用來供 Linux 內核開發使用的,而那意味著從一開始它就需要高效處理大型庫。 此外,Git 是用 C 語言編寫的,這減少了運行期與高層語言進行協作的開銷。Git 這么快的另一個原因是它的主要開發者把這當成設計目標。
我使用 Git,Mercurial 和 Bazaar 這三個不同的 SCM 各存放一份 Django 的源代碼,進行了一些測試,下面是一些測試結果。 我也用 SVN 進行了一些測試,不過相應我,它要更慢 — 基本上是 Bazaar 的測試結果加上網絡延遲...
測試結果表明除了增加新文件以外,所有的操作都是 Git 最快。(此外在一些非常大的提交操作測試中,Hg 基本上與 Git 一樣快,不過我測試的那種提交操作實在太大, 你不大可能會遇到那種情況 — Git 處理普通提交比其他 SCM 要快得多)
| Git | Hg | Bzr |
Init | 0.024s | 0.059s | 0.600s |
Add | 8.535s | 0.368s | 2.381s |
Status | 0.451s | 1.946s | 14.744s |
Diff | 0.543s | 2.189s | 14.248s |
Tag | 0.056s | 1.201s | 1.892s |
Log | 0.711s | 2.650s | 9.055s |
Commit (Large) | 12.480s | 12.500s | 23.002s |
Commit (Small) | 0.086s | 0.517s | 1.139s |
Branch (Cold) | 1.161s | 94.681s | 82.249s |
Branch (Hot) | 0.070s | 12.300s | 39.411s |
Cold 和 Hot 是第一次和第二次對一個庫進行分支操作的結果數字 — 第二次分支使用了硬盤緩存。
需要注意的是雖然 'add' 操作 Git 要慢很多,但這是在大量文件 — 超過 2000 個 — 上進行的新增操作。 對于大部分人的日常工作來說,任意一個系統上的新增操作只會花費幾分之一秒。其他測試到的操作(可能除了大提交)都與日常使用到的相近。
這些測試結果并不難重現。只要用不同系統復制一份 Django 工程就可以比較出來了。
git clone git://github.com/brosner/django.git dj-git
hg clone http://hg.dpaste.com/django/trunk dj-hg
bzr branch lp:django dj-bzr
svn checkout http://code.djangoproject.com/svn/django/trunk dj-svn
svn
Git 真的非常善于節省磁盤空間。你的 Git 目錄一般只會比一個 SVN checkout 大一點點 — 有時更小(顯然 .svn 目錄中的許多內容可以去掉)。
從 Django 工程 的同一個歷史紀錄點取出的不同部分的 clone,提供給我們這些數據。
| Git | Hg | Bzr | Bzr* | SVN |
Repo Alone | 24M | 34M | 45M | 89M |
|
Entire Directory | 43M | 53M | 64M | 108M | 61M |
* 第二個 Bar 數字是我執行 'bzr pack' 后得到的,我本以為該命令會讓它體積變小,但結果反而讓它變得大得多。
hg bzr svn perforce
不同于其他系統,Git 有它稱之為暫存區域("staging area")或 "index" 的東西。 這是一個用來在提交前對提交內容進行設置的臨時區域。
暫存區域最酷、也是讓 Git 不同于其他工具的地方,是在你完成一部分文件的修改后,可以方便地 stage 并提交它們,同時又不用提交工作目錄中其他已修改的文件或在提交命令中列出那些文件。
你還可以只 stage 已修改的一個文件的一部分內容。再也不會發生這樣的事情了:對同一個文件中邏輯上并不相關的兩部分進行修改后才發現沒有對它們進行分別提交。 現在你可以先 stage 當前提交要包括的修改,然后 stage 下次提交要包括的修改。這一特性適用于你需要對文件進行的任意范圍的修改。
當然,如果你不想控制這么多,你也可以很輕松的忽略這些特性 — 只需在提交命令上加上 '-a' ,就可以把所有修改過的文件加入到暫存區域中去了。
svn perforce
包括 Git 在內的所有分布式 SCM 的最佳特性之一是分布式。這意味著你不是 "checkout" 源代碼的最新版,而是 "clone" 整個代碼庫。
這意味著即使使用中央集中式的工作流,每一個用戶都擁有一份主服務器的備份,每一份都可以在主服務器當機或損壞時用來替換它。使用 Git 便不存在單點故障了,除非只有一個點。
同時這不會使操作變得太慢。平均來說,SVN checkout 只比任何一種分布式 SCM 快一點。在我測試過的分布式 SCM 中,Git 是最快的。
| Git | 1m 59s | Hg | 2m 24s | Bzr | 5m 11s | SVN | 1m 4s | |
svn perforce
Git 令人驚嘆的特性之一是,由于其天生的分布式特征及強大的分支系統,可以輕而易舉的應用任何想的到的工作流。
Subversion 式的工作流
集中式工作流是一種很常見的工作流,這對于那些從集中式系統遷移過來的人來說尤其如此。如果你上次 fetch 過后,已經有其他人進行了 push 操作,那么 Git 將不允許你直接 push; 所以這種所有開發者向同一臺服務器 push 的集中式模型可以工作的很好。
集成管理員工作流
另一種常見工作流是有一名集成管理員專門負責向 'blessed' 庫提交,其他開發者復制該庫,push 到他們自己獨立的庫,隨后請求集成管理員 pull 他們的修改。 這是開源工程或 GitHub 庫中很常見的一種開發模式。
司令官與副官工作流
對于規模更龐大的項目,你可以讓開發者使用類似 Linux 內核開發的工作流,每一個子系統都有專人(副官)負責合并與該子系統相關的修改。 另有一名整合者(司令官)只從副官那里 pull ,然后 push 到 'blessed' 庫,其他所有人則再從 'blessed' 庫復制。
再次強調,對于工作流 Git 非常有彈性,你可以混合及選用任何適合你的工作流。
hg bzr svn perforce
我本人在
GitHub 工作,所以這
可能 顯得有點偏頗, 不過我還是加入了這一部分,因為很多人說正是 GitHub 讓他們選擇了 Git 。
GitHub 是很多人使用 Git 的原因,相比簡單的托管網站,它更象一個社交網絡。 人們找到與他們在做的事相關(似)的其他開發人員或項目,然后輕松地 fork 和貢獻,這樣形成了一個以 Git 和 各種項目為中心的活躍社區。
也有其他許多針對 Git 和其他 SCM 的服務,但很少有用戶導向或社交導向的,更沒有哪個是基于用戶群的。 GitHub 的社交性是殺手級特性,上述特性使得 Git 和 GitHub 成為快速開發開源項目的最佳組合。
其他任何一種 SCM 都不提供這樣的社區。
perforce
本來并非如此 — 早期的 Git 并不是真正意義上的 SCM,而更象一套讓你可以用分布式的方式進行版本控制的工具。 但是現在 Git 命令集和學習曲線已經和其他 SCM 類似,甚至比其中一些更好。
不作針對性的研究很難證明這一點,在此我僅僅演示一下 Mercurial 和 Git 命令中的默認幫助菜單的區別。這兩個系統中相同(或相近)的命令將被高亮顯示。 (在 Hg 中,如果你輸入 'hg help',你會得到一份 40 多個命令的清單。)
Mercurial Help add add the specified files ... annotate show changeset informati... clone make a copy of an existi... commit commit the specified fil... diff diff repository (or sele... export dump the header and diff... init create a new repository ... log show revision history of... merge merge working directory ... parents show the parents of the ... pull pull changes from the sp... push push changes to the spec... remove remove the specified fil... serve export the repository vi... status show changed files in th... update update working directory
| Git Help add Add file contents to the index bisect Find the change that introduce... branch List, create, or delete branches checkout Checkout a branch or paths to ... clone Clone a repository into a new ... commit Record changes to the repository diff Show changes between commits, ... fetch Download objects and refs from... grep Print lines matching a pattern init Create an empty git repository log Show commit logs merge Join two or more development h... mv Move or rename a file, a direc... pull Fetch from and merge with anot... push Update remote refs along with ... rebase Forward-port local commits to ... reset Reset current HEAD to the spec... rm Remove files from the working ... show Show various types of objects status Show the working tree status tag Create, list, delete or verify...
|
在 Git 1.6 之前,所有 Git 命令都存放在可執行路徑下,這讓使用者非常迷惑。 現在雖然 Git 仍能識別所有這些命令,但存放在可執行路徑下的只有 'git' 這一命令。 如果你比較 Mercurial 和 Git 會發現,Git 的命令集與幫助系統與 Mercurial 幾乎完全一樣 — 從初學者的 UI 角度來說兩者幾乎沒有區別。
現在已經很難說 Mercurial 或 Bazaar 比 Git 更易學了。
原文:http://zh-cn.whygitisbetterthanx.com/
http://zh-cn.whygitisbetterthanx.com/