關於 Git 你需要知道的一些事情
分支和合並
Git 跟其他版本控制系統最大的優勢就在於其高階的分支模型。
Git 允許而且 鼓勵 你在本地使用多個完全獨立的分支。這些分支的建立,合併和刪除幾乎都可以在幾秒內完成。
這意味著你可以輕鬆的做如下操作:
- 無痛的上下文切換 建立分支試驗一個想法,提交幾次,切回你原來分支的狀態,應用一個改動 patch,切回你原來正在試驗的狀態,將剛才應用的 patch 合併過來。
- 基於角色的程式碼支線 你可能會有一個分支僅僅包含那些只存在於生產環境上的程式碼,另外有一個獨立的分支用以合併測試環境程式碼,還有若干個更小一些的分支用於日常開發工作
- 基於特性的工作流 為每一個新的特性建立新的分支,你可以方便平滑的在這些分支之間無縫切換,當這些特性的改動完成的時候,你可以將其合併入主分支,並把特性分支刪掉。
- 任意試驗 建立一個分支專門用來試驗,當覺得試驗不理想的時候,直接刪除掉即可,放棄掉之前的試驗內容。這時候不會有任何其他人察覺到這個試驗(甚至在這期間你還可以推送其他不相關的分支)
尤其是當你推送至遠端倉庫的時候,你不必推送所有分支,你可以選擇只推送少數你願意分享的分支,當然如果你願意,也可以推送所有分支。這一點傾向於讓開發者在試驗很多新的想法的時候免除釋出自己的未成熟的試驗計劃的顧慮。
當然,也有一些其他的系統可以部分實現上述的功能和優勢,只是具體的執行會變的困難和容易出錯。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 擁有分散式特性和極好的分支系統,你可以在此基礎上輕鬆實現大量的工作流模型。
Subversion(SVN) 風格工作流
集中式儲存的工作流非常常見,特別是對於那些從傳統的集中式程式碼版本管理系統轉過來使用 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 避免爭議。欲知詳情請看我們的商標政策。
相關文章
- [譯] 關於 `ExpressionChangedAfterItHasBeenCheckedError` 錯誤你所需要知道的事情ExpressError
- 關於 jwt 你應該知道的事情JWT
- 關於 Git 你所不知道的一些事Git
- 關於軟體開發你真正需要知道的幾個事情
- 關於字元編碼你應該知道的事情字元
- 【譯】關於JavaScript 陣列你應該知道的事情JavaScript陣列
- 關於跨域你需要知道的跨域
- 你應該知道的10件關於Java 6的事情Java
- 關於CSS Transition,你需要知道的事CSS
- 關於MongoDB你需要知道的幾件事MongoDB
- 【譯】關於 JavaScript 的原型你應該知道的所有事情JavaScript原型
- 你應該知道的10件關於Java 6的事情(轉)Java
- 關於網校系統原始碼,你不知道的事情原始碼
- 關於Android模組化你需要知道的Android
- 關於字元編碼,你所需要知道的字元
- [譯] 關於 Angular 動態元件你需要知道的Angular元件
- 關於webpack優化,你需要知道的事(上篇)Web優化
- 關於C++14:你需要知道的新特性C++
- 你需要知道的關於 Go 包的一切Go
- 說一說 React 和 Redux 你知道或者不知道的一些事情ReactRedux
- 關於進入遊戲行業你需要知道的事遊戲行業
- 【ASK_ORACLE】關於Oracle索引分裂你需要知道的Oracle索引
- 關於Android的.so檔案你所需要知道的Android
- 你需要知道的12個Git高階命令Git
- 關於如何更改Cuda的版本的一些事情
- 關於神經網路:你需要知道這些神經網路
- Git——關於Git的一些補充(1)Git
- 關於Vue v-model你需要知道的一切Vue
- 關於 v-model 你需要知道的這一切!
- 關於 Linux 程式你所需要知道的一切Linux
- Google I\/O:關於產品變現你需要知道的Go
- 關於單例模式,你需要知道的幾種寫法單例模式
- 關於Git小白應該知道的事Git
- 關於ES模組你必須要知道的一些禁忌(一)
- 關於專案採購管理,這些你需要知道
- 關於Android Gradle你需要知道這些(4)AndroidGradle
- 關於Android Gradle你需要知道這些(3)AndroidGradle
- 關於Android Gradle你需要知道這些(1)AndroidGradle