Git 跟其餘版本控制系統最大的優點就在於其高級的分支模型。git
Git 容許並且 鼓勵 你在本地使用多個徹底獨立的分支。這些分支的建立,合併和刪除幾乎均可以在幾秒內完成。編程
這意味着你能夠輕鬆的作以下操做:服務器
尤爲是當你推送至遠程倉庫的時候,你沒必要推送全部分支,你能夠選擇只推送少數你願意分享的分支,固然若是你願意,也能夠推送全部分支。這一點傾向於讓開發者在試驗不少新的想法的時候免除發佈本身的未成熟的試驗計劃的顧慮。markdown
固然,也有一些其餘的系統能夠部分實現上述的功能和優點,只是具體的執行會變的困難和容易出錯。Git 讓這些工做變得難以置信的簡單,它在開發者學習其使用的同時就改變了開發者的工做模式。網絡
Git 很快。Git 基本上全部的操做都在本地執行,這對於那些必須跟服務器通訊的集中式系統是一個巨大的速度優點。編程語言
Git 一開始是爲了管理 Linux Kernel 的源代碼設計的,這意味着他從第一天誕生就擁有了處理大型倉庫的高效優點。Git 使用 C 語言編寫,減輕了使用更高級別編程語言的 Runtime 帶來的性能損耗。Git 最開始的兩個重要的設計目標就是性能和速度。分佈式
讓咱們看一下與 SVN (一個通用的集中式存儲版本控制系統,跟 CVS 和 Perforce 很像)相比下的常規操做的性能測試指標。這裏指標是值越小,速度越快。工具
爲了測試,咱們在亞馬遜的 AWS 的一樣的可用區上新建了兩個 Large 類型的計算服務器實例。每個計算實例上都安裝 Git 和 SVN。 咱們把 Ruby 的源代碼倉庫拷貝到了 Git 和 SVN 的計算服務器示例上,二者都執行通用的操做。性能
在有些狀況下,二者的命令和實際效果並不能徹底對應起來。在這裏,咱們在經常使用的操做中選擇類似效果的匹配狀況。例如,對於 「提交」 的測試,在 Git 中咱們也是計算 Push 的時間的。然而在大多數狀況下,你可能實際上並不會在提交後立刻就推送到服務器上,這在 SVN 上是不可分割的操做。學習
下面表格中全部的時間單位都是秒。
操做 | 描述 | Git | SVN | 性能倍數 |
---|---|---|---|---|
提交文件 (A) | Add, commit and push 113 modified files (2164+, 2259-) | 0.64 | 2.60 | 4x |
提交圖片 (B) | Add, commit and push 1000 1k images | 1.53 | 24.70 | 16x |
對比當前變更 | Diff 187 changed files (1664+, 4859-) against last commit | 0.25 | 1.09 | 4x |
對比最近的變更 | Diff against 4 commits back (269 changed/3609+,6898-) | 0.25 | 3.99 | 16x |
對比標籤 | Diff two tags against each other (v1.9.1.0/v1.9.3.0) | 1.17 | 83.57 | 71x |
提交歷史 (50) | Log of the last 50 commits (19k of output) | 0.01 | 0.38 | 31x |
提交歷史 (所有) | Log of all commits (26,056 commits - 9.4M of output) | 0.52 | 169.20 | 325x |
提交歷史 (文件) | Log of the history of a single file (array.c - 483 revs) | 0.60 | 82.84 | 138x |
更新 | Pull of Commit A scenario (113 files changed, 2164+, 2259-) | 0.90 | 2.82 | 3x |
Blame | Line annotation of a single file (array.c) | 1.91 | 3.04 | 1x |
你須要注意的是,這已是 SVN 最好的運行場景了 -- 一個沒有任何負載的服務器,客戶端和服務器之間的網絡帶寬達到 80MB/s。上文中的全部指標在受網絡波動,或者在一個更差的網絡環境下 SVN 的表現都更差,然而 Git 這邊幾乎全部的指標都不受影響。
很明顯,在這些最經常使用的版本控制工具的操做中,甚至是在 SVN 的理想使用環境下,**Git 在不少方面都大幅領先 **。
一個 Git 比 SVN 慢的地方是初始化 clone 倉庫。在這種狀況下,Git 是在下載整個倉庫歷史而不是僅僅是最新版本的代碼。上文中的表格所示,僅僅執行一次的操做影響並非很大。
操做 | 描述 | Git(Shallow Clone) | Git | SVN |
---|---|---|---|---|
Clone | Git Clone 以及 shallow clone(淺 clone) vs SVN checkout | 21.0 | 107.5 | 14.0 |
大小 (M) | 客戶端在 clone/checkout 後的文件大小 (以 M 爲單位) | 181.0 | 132.0 |
另一個有趣的點是,Git 和 SVN 在 Clone 或者 Checkout 到本地後的文件大小几乎差異不大,要知道對於 Git 來講,本地但是包含了整個項目歷史。這也展現了 Git 在文件壓縮和存儲上的超高效率。
Git 最棒的特性之一就是分佈式。這意味着,你要 clone 整個倉庫而不是僅僅 checkout 分支的最新頭部版本。
在平常的使用場景中 Git 每每有多個備份。這意味着就算在使用一箇中央存儲式的工做流,每個用戶都在本地有一個服務器上的完整備份。這裏的任意一個版本均可以在服務器端數據損壞或者丟失的時候推送回服務器以挽救損失。事實上,只要你的倉庫不是隻有一個 copy,Git 就不會存在單點問題。
由於 Git 擁有分佈式特性和極好的分支系統,你能夠在此基礎上輕鬆實現大量的工做流模型。
集中式存儲的工做流很是常見,特別是對於那些從傳統的集中式代碼版本管理系統轉過來使用 Git 的人。Git 同樣能夠提供這種工做形式:每次 Push 必需要更新到遠程倉庫的最新版本。因此說你們仍是像之前同樣使用集中式存儲的工做流往同一個服務器上 Push 代碼依然沒問題。
另一個常見的 Git 工做流是整合工做流。主要的倉庫有一個單一的開發者維護(維護者)。其餘若干開發者從這個倉庫 clone,而後推送到他們本身的徹底獨立的倉庫裏面,最後請求維護者從主要倉庫 Pull 那些他們在各自的倉庫裏面的改動。這種形式每每在 GitHub 上以開源的形式進行協做。
對於一些更爲複雜的項目來說,像 Linux 內核這樣的開發工做流也是頗有效的。在這個模型中,負責人(lieutenants)負責整個項目的一些特定的子系統,他們合併全部跟那個子系統關聯的變更。另一個維護者(dictator,字面理解:獨裁者)只能從他管轄的負責人這裏獲取變動,並將這些變動推送到主要倉庫。而後全部人都從這個倉庫獲取更新。
Git 的數據模型確保了項目內的每個字節,每個 bit 的一致性。提交的每個文件都會使用校驗和計算摘要,檢出的時候也使用這個摘要值。沒有任何可能會出現從倉庫中獲取的內容跟你存儲的內容有任何差別。
在不改變 ID(校驗和)的狀況下也不可能出現改變任何文件,日期,提交說明或者任何其餘在 Git 倉庫中的數據。這就意味着,若是你有一個 commit ID,你不但能夠肯定這個版本的代碼跟他提交的時候是如出一轍的,並且這個版本以前的歷史也沒有發生任何改變。
大多數中央存儲的版本控制系統默認不提供這樣的校驗整合。
不像其餘系統, Git 有一個概念叫作 「暫存區域」 或者 「index」。這是一個在提交執行以前的臨時的區域能夠用來格式化和審閱改動內容的。
一個 Git 優於其餘系統的功能是咱們能夠快速的暫存一些改動的文件,在工做目錄中只提交部分改動的文件,或者文件改動的部份內容,以及在提交的時候在命令行裏列出改動的文件列表。
暫存區域容許你僅僅暫存部分的文件改動,在你意識到你忘了提交其中一個文件以前,對文件進行兩個邏輯上不相關的修改的日子已經一去不復返了。如今你能夠僅僅暫存你當前提交須要改動的文件,其餘的改動在下次提交再暫存。這個特性能夠擴展到對文件進行的任何更改。
固然,Git 也容許你忽略掉暫存區域這個過程,你能夠輕鬆的在 commit 命令後面添加 '-a' 選項來直接將全部改動提交。Git 會自動幫你先暫存到暫存區域,再執行提交。
Git 是一個使用 GNU GPL2.0 協議的開源軟件。Git 選擇 GPLv2 來確保你能夠自由的分享和改造自由軟件,並且能確保使用它的任何用戶都是自由免費的。
然而,咱們確實也保留了 「Git」 和 logos 避免爭議。欲知詳情請看咱們的商標政策。
譯者注
本文譯自 Git 官方網站的關於說明