1. 程式人生 > >git基礎:《Git 分支》學習筆記

git基礎:《Git 分支》學習筆記

兩件 創建 筆記 it基礎 其它 版本控制 情況 bject 為什麽

Git 保存的不是文件的變化或者差異,而是一系列不同時刻的文件快照。在進行提交操作時,Git 會保存一個提交對象(commit object)。該提交對象包含一個指向暫存內容快照的指針,該提交對象還包含了作者的姓名和郵箱、提交時輸入的信息以及指向它的父對象的指針。首次提交產生的提交對象沒有父對象,普通提交操作產生的提交對象有一個父對象,而由多個分支合並產生的提交對象有多個父對象。

當使用 git commit 進行提交操作時,Git 會先計算每一個子目錄(本例中只有項目根目錄)的校驗和,然後在 Git 倉庫中這些校驗和保存為樹對象。 隨後,Git 便會創建一個提交對象,它除了包含上面提到的那些信息外,還包含指向這個樹對象(項目根目錄)的指針。如此一來,Git 就可以在需要的時候重現此次保存的快照。

分支創建

Git 是怎麽創建新分支的呢? 很簡單,它只是為你創建了一個可以移動的新的指針。 比如,創建一個 testing 分支, 你需要使用 git branch 命令:

$ git branch testing

這僅僅是在當前所在的提交對象上創建一個指針。

那麽,Git 又是怎麽知道當前在哪一個分支上呢? 也很簡單,它有一個名為 HEAD 的特殊指針。 請註意它和許多其它版本控制系統(如 Subversion 或 CVS)裏的 HEAD 概念完全不同。 在 Git 中,它是一個指針,指向當前所在的本地分支(譯註:將 HEAD 想象為當前分支的別名)。 在本例中,你仍然在 master 分支上。 因為 git branch 命令僅僅 創建 一個新分支,並不會自動切換到新分支中去。你可以簡單地使用 git log 命令查看各個分支當前所指的對象。 提供這一功能的參數是 --decorate。

技術分享圖片

正如你所見,當前 “master” 和 “testing” 分支均指向校驗和以 3be3f33 開頭的提交對象。

分支切換

要切換到一個已存在的分支,你需要使用 git checkout 命令。 我們現在切換到新創建的 testing 分支去:

$ git checkout testing

這樣 HEAD 就指向 testing 分支了。那麽,這樣的實現方式會給我們帶來什麽好處呢? 現在不妨再提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'

技術分享圖片

如圖所示,你的 testing 分支向前移動了,但是 master 分支卻沒有,它仍然指向運行 git checkout 時所指的對象。 這就有意思了,現在我們切換回 master 分支看看:

git checkout master

技術分享圖片

這條命令做了兩件事。 一是使 HEAD 指回 master 分支,二是將工作目錄恢復成 master 分支所指向的快照內容。 也就是說,你現在做修改的話,項目將始於一個較舊的版本。 本質上來講,這就是忽略 testing 分支所做的修改,以便於向另一個方向進行開發。

分支切換會改變你工作目錄中的文件
在切換分支時,一定要註意你工作目錄裏的文件會被改變。 如果是切換到一個較舊的分支,你的工作目錄會恢復到該分支最後一次提交時的樣子。 如果 Git 不能幹凈利落地完成這個任務,它將禁止切換分支。

我們不妨再稍微做些修改並提交:

$ vim test.rb
$ git commit -a -m 'made other changes'

現在,這個項目的提交歷史已經產生了分叉(參見 項目分叉歷史)。 因為剛才你創建了一個新分支,並切換過去進行了一些工作,隨後又切換回 master 分支進行了另外一些工作。 上述兩次改動針對的是不同分支:你可以在不同分支間不斷地來回切換和工作,並在時機成熟時將它們合並起來。 而所有這些工作,你需要的命令只有 branch、checkout 和 commit。

你可以簡單地使用 git log 命令查看分叉歷史。 運行 git log --oneline --decorate --graph --all ,它會輸出你的提交歷史、各個分支的指向以及項目的分支分叉情況。

技術分享圖片

由於 Git 的分支實質上僅是包含所指對象校驗和(長度為 40 的 SHA-1 值字符串)的文件,所以它的創建和銷毀都異常高效。 創建一個新分支就相當於往一個文件中寫入 41 個字節(40 個字符和 1 個換行符),如此的簡單能不快嗎?

這與過去大多數版本控制系統形成了鮮明的對比,它們在創建分支時,將所有的項目文件都復制一遍,並保存到一個特定的目錄。 完成這樣繁瑣的過程通常需要好幾秒鐘,有時甚至需要好幾分鐘。所需時間的長短,完全取決於項目的規模。而在 Git 中,任何規模的項目都能在瞬間創建新分支。 同時,由於每次提交都會記錄父對象,所以尋找恰當的合並基礎(譯註:即共同祖先)也是同樣的簡單和高效。 這些高效的特性使得 Git 鼓勵開發人員頻繁地創建和使用分支。

接下來,讓我們看看你為什麽應該這樣做。

git基礎:《Git 分支》學習筆記