分支簡介
分支創建
master
。
在多次提交操作之後,你其實已經有一個指向最後那個提交對象的 master
分支。
它會在每次的提交操作中自動向前移動。
Git 是怎麼創建新分支的呢? 很簡單,它只是爲你創建了一個可以移動的新的指針。 比如,創建一個 testing 分支, 你需要使用 git
branch
命令:
$
git branch testing
這會在當前所在的提交對象上創建一個指針。
那麼,Git 又是怎麼知道當前在哪一個分支上呢? 也很簡單,它有一個名爲 HEAD
的特殊指針。 請注意它和許多其它版本控制系統(如
Subversion 或 CVS)裏的 HEAD
概念完全不同。 在 Git 中,它是一個指針,指向當前所在的本地分支(譯註:將 HEAD
想象爲當前分支的別名)。
在本例中,你仍然在 master
分支上。 因爲 git
branch
命令僅僅 創建 一個新分支,並不會自動切換到新分支中去。
分支切換
要切換到一個已存在的分支,你需要使用 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
分支所做的修改,以便於向另一個方向進行開發。
NOTE
分支切換會改變你工作目錄中的文件
在切換分支時,一定要注意你工作目錄裏的文件會被改變。 如果是切換到一個較舊的分支,你的工作目錄會恢復到該分支最後一次提交時的樣子。 如果 Git 不能幹淨利落地完成這個任務,它將禁止切換分支。
我們不妨再稍微做些修改並提交:
$
vim test.rb$
git commit -a -m'made other changes'
現在,這個項目的提交歷史已經產生了分叉(參見 Figure 3-9)。 因爲剛纔你創建了一個新分支,並切換過去進行了一些工作,隨後又切換回 master
分支進行了另外一些工作。 上述兩次改動針對的是不同分支:你可以在不同分支間不斷地來回切換和工作,並在時機成熟時將它們合併起來。 而所有這些工作,你需要的命令只有 branch
、checkout
和 commit
。
由於 Git 的分支實質上僅是包含所指對象校驗和(長度爲 40 的 SHA-1 值字符串)的文件,所以它的創建和銷燬都異常高效。 創建一個新分支就像是往一個文件中寫入 41 個字節(40 個字符和 1 個換行符),如此的簡單能不快嗎?
這與過去大多數版本控制系統形成了鮮明的對比,它們在創建分支時,將所有的項目文件都複製一遍,並保存到一個特定的目錄。 完成這樣繁瑣的過程通常需要好幾秒鐘,有時甚至需要好幾分鐘。所需時間的長短,完全取決於項目的規模。而在 Git 中,任何規模的項目都能在瞬間創建新分支。 同時,由於每次提交都會記錄父對象,所以尋找恰當的合併基礎(譯註:即共同祖先)也是同樣的簡單和高效。 這些高效的特性使得 Git 鼓勵開發人員頻繁地創建和使用分支。