3.1 分支簡介

2018-02-24 15:22 更新

分支簡介

為了真正理解 Git 處理分支的方式,我們需要回顧一下 Git 是如何保存數(shù)據(jù)的。

或許你還記得 Chapter?1 的內(nèi)容,Git 保存的不是文件的變化或者差異,而是一系列不同時(shí)刻的文件快照。

在進(jìn)行提交操作時(shí),Git 會(huì)保存一個(gè)提交對象(commit object)。知道了 Git 保存數(shù)據(jù)的方式,我們可以很自然的想到——該提交對象會(huì)包含一個(gè)指向暫存內(nèi)容快照的指針。但不僅僅是這樣,該提交對象還包含了作者的姓名和郵箱、提交時(shí)輸入的信息以及指向它的父對象的指針。首次提交產(chǎn)生的提交對象沒有父對象,普通提交操作產(chǎn)生的提交對象有一個(gè)父對象,而由多個(gè)分支合并產(chǎn)生的提交對象有多個(gè)父對象,

為了說得更加形象,我們假設(shè)現(xiàn)在有一個(gè)工作目錄,里面包含了三個(gè)將要被暫存和提交的文件。暫存操作會(huì)為每一個(gè)文件計(jì)算校驗(yàn)和(使用我們在 Chapter?1 中提到的 SHA-1 哈希算法),然后會(huì)把當(dāng)前版本的文件快照保存到 Git 倉庫中(Git 使用 blob 對象來保存它們),最終將校驗(yàn)和加入到暫存區(qū)域等待提交:

$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'

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

現(xiàn)在,Git 倉庫中有五個(gè)對象:三個(gè) blob 對象(保存著文件快照)、一個(gè)樹對象(記錄著目錄結(jié)構(gòu)和 blob 對象索引)以及一個(gè)提交對象(包含著指向前述樹對象的指針和所有提交信息)。

Figure 3-2. 提交對象及其父對象

Git 的分支,其實(shí)本質(zhì)上僅僅是指向提交對象的可變指針。Git 的默認(rèn)分支名字是 master。在多次提交操作之后,你其實(shí)已經(jīng)有一個(gè)指向最后那個(gè)提交對象的 master 分支。它會(huì)在每次的提交操作中自動(dòng)向前移動(dòng)。

Git 的 “master” 分支并不是一個(gè)特殊分支。它就跟其它分支完全沒有區(qū)別。之所以幾乎每一個(gè)倉庫都有 master 分支,是因?yàn)?git init 命令默認(rèn)創(chuàng)建它,并且大多數(shù)人都懶得去改動(dòng)它。

Figure 3-4. 兩個(gè)指向相同提交歷史的分支

那么,Git 又是怎么知道當(dāng)前在哪一個(gè)分支上呢?也很簡單,它有一個(gè)名為 HEAD 的特殊指針。請注意它和許多其它版本控制系統(tǒng)(如 Subversion 或 CVS)里的 HEAD 概念完全不同。在 Git 中,它是一個(gè)指針,指向當(dāng)前所在的本地分支(譯注:將 HEAD 想象為當(dāng)前分支的別名)。在本例中,你仍然在 master 分支上。因?yàn)?git branch 命令僅僅 創(chuàng)建 一個(gè)新分支,并不會(huì)自動(dòng)切換到新分支中去。

Figure 3-6. HEAD 指向當(dāng)前所在的分支

那么,這樣的實(shí)現(xiàn)方式會(huì)給我們帶來什么好處呢?現(xiàn)在不妨再提交一次:

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

Figure 3-8. 檢出時(shí) HEAD 隨之移動(dòng)

這條命令做了兩件事。一是使 HEAD 指回 master 分支,二是將工作目錄恢復(fù)成 master 分支所指向的快照內(nèi)容。也就是說,你現(xiàn)在做修改的話,項(xiàng)目將始于一個(gè)較舊的版本。本質(zhì)上來講,這就是忽略 testing 分支所做的修改,以便于向另一個(gè)方向進(jìn)行開發(fā)。

分支切換會(huì)改變你工作目錄中的文件

在切換分支時(shí),一定要注意你工作目錄里的文件會(huì)被改變。如果是切換到一個(gè)較舊的分支,你的工作目錄會(huì)恢復(fù)到該分支最后一次提交時(shí)的樣子。如果 Git 不能干凈利落地完成這個(gè)任務(wù),它將禁止切換分支。

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

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

現(xiàn)在,這個(gè)項(xiàng)目的提交歷史已經(jīng)產(chǎn)生了分叉(參見 Figure?3-9)。因?yàn)閯偛拍銊?chuàng)建了一個(gè)新分支,并切換過去進(jìn)行了一些工作,隨后又切換回 master 分支進(jìn)行了另外一些工作。上述兩次改動(dòng)針對的是不同分支:你可以在不同分支間不斷地來回切換和工作,并在時(shí)機(jī)成熟時(shí)將它們合并起來。而所有這些工作,你需要的命令只有 branch、checkoutcommit

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號