前言
暫存區(qū)(stage, index)
是Git
最重要的概念之一,理解了這個(gè)概念很多 Git
命令就不再那么神秘了名秀。下面幾個(gè)驗(yàn)證例子一開始看不懂沒關(guān)系励负,工作區(qū)、版本庫(kù)中的暫存區(qū)和版本庫(kù)之間的關(guān)系圖先理解先匕得。
正文
下面這個(gè)圖展示了工作區(qū)继榆、版本庫(kù)中的暫存區(qū)和版本庫(kù)之間的關(guān)系。
在這個(gè)圖中汁掠,我們可以看到部分
Git
命令是如何影響工作區(qū)和暫存區(qū)(stage, index)
的略吨。
- 圖中左側(cè)為工作區(qū),右側(cè)為版本庫(kù)考阱。在版本庫(kù)中標(biāo)記為
index
的區(qū)域是暫存區(qū)(stage, index)
翠忠,標(biāo)記為master
的是master
分支所代表的目錄樹。 - 圖中我們可以看出此時(shí)
HEAD
實(shí)際是指向master
分支的一個(gè)“游標(biāo)”乞榨。所以圖示的命令中出現(xiàn)HEAD
的地方可以用master
來(lái)替換秽之。 - 圖中的
objects
標(biāo)識(shí)的區(qū)域?yàn)?code>Git的對(duì)象庫(kù)当娱,實(shí)際位于.git/objects
目錄下,我們會(huì)在后面的章節(jié)重點(diǎn)介紹政溃。 - 當(dāng)對(duì)工作區(qū)修改(或新增)的文件執(zhí)行
git add
命令時(shí)趾访,暫存區(qū)的目錄樹被更新,同時(shí)工作區(qū)修改(或新增)的文件內(nèi)容被寫入到對(duì)象庫(kù)中的一個(gè)新的對(duì)象中董虱,而該對(duì)象的ID
被記錄在暫存區(qū)的文件索引中扼鞋。 - 當(dāng)執(zhí)行提交操作
(git commit)
時(shí),暫存區(qū)的目錄樹寫到版本庫(kù)(對(duì)象庫(kù))中愤诱,master
分支會(huì)做相應(yīng)的更新云头。即master
指向的目錄樹就是提交時(shí)暫存區(qū)的目錄樹。 - 當(dāng)執(zhí)行
git reset HEAD
命令時(shí)淫半,暫存區(qū)的目錄樹會(huì)被重寫溃槐,被 master 分支指向的目錄樹所替換,但是工作區(qū)不受影響科吭。 - 當(dāng)執(zhí)行
git checkout .
或者git checkout -- [file]
命令時(shí)昏滴,會(huì)用暫存區(qū)全部或指定的文件替換工作區(qū)的文件。這個(gè)操作很危險(xiǎn)对人,會(huì)清除工作區(qū)中未添加到暫存區(qū)的改動(dòng)谣殊。 - 當(dāng)執(zhí)行
git checkout HEAD .
或者git checkout HEAD [file]
命令時(shí),會(huì)用HEAD
指向的master
分支中的全部或者部分文件替換暫存區(qū)和以及工作區(qū)中的文件牺弄。這個(gè)命令也是極具危險(xiǎn)性的姻几,因?yàn)椴坏珪?huì)清除工作區(qū)中未提交的改動(dòng),也會(huì)清除暫存區(qū)中未提交的改 動(dòng)势告。 - 當(dāng)執(zhí)行
git rm --cached [file]
命令時(shí)蛇捌,會(huì)直接從暫存區(qū)刪除文件,工作區(qū)則不做出改變咱台。 - 當(dāng)執(zhí)行
git rm file
命令時(shí)络拌,會(huì)同時(shí)刪除暫存區(qū)和工作區(qū)的文件。 - 當(dāng)執(zhí)行
rm file
命令時(shí)回溺,只會(huì)刪除工作區(qū)的文件盒音。
下面舉例子來(lái)證明以上觀點(diǎn)
假設(shè):
工作區(qū):a
暫存區(qū)(index):b
HEAD:C
git diff命令結(jié)論
git diff 比較a跟b
git diff --cached 比較b跟c
git diff HEAD 比較a跟c
git reset跟 git checkout結(jié)論
git reset HEAD c覆蓋b
git checkout -- <file> b覆蓋a
git checkout HEAD <file> c覆蓋a,b
git rm命令結(jié)論
git rm 刪除a跟b
git rm --cached 只刪除b
rm file 只刪除a
證明git diff結(jié)論
例子,默認(rèn)新建一個(gè)readme.txt
馅而,里面輸入內(nèi)容one
然后add并且commit
一次。
1:修改readme.txt
譬圣,新增內(nèi)容two
瓮恭,這時(shí)候a內(nèi)容改變了,多了two
,而b跟c內(nèi)容不變厘熟,都只有one
屯蹦。
執(zhí)行git diff readme.txt
查看效果
結(jié)論:如圖看出维哈,內(nèi)容有修改, a跟b比較了
執(zhí)行git diff --cached readme.txt
查看效果
結(jié)論:如圖看出登澜,沒有變化阔挠,因?yàn)閎跟c內(nèi)容一樣。
執(zhí)行git diff HEAD readme.txt
查看效果
如圖所示:內(nèi)容有修改脑蠕,a跟c比較了
2.這時(shí)候執(zhí)行git add readme.txt
,這時(shí)候a购撼,b內(nèi)容都多了two,而c內(nèi)容不變谴仙,只有one
執(zhí)行git diff readme.txt
查看效果
結(jié)論:如圖看出迂求,沒有變化, 因?yàn)閍跟b內(nèi)容一樣。
執(zhí)行g(shù)it diff --cached readme.txt查看效果
結(jié)論:如圖看出,內(nèi)容有修改珍特,b跟c比較了
執(zhí)行git diff HEAD readme.txt
查看效果
結(jié)論:如圖看出差油,內(nèi)容有修改,a跟c比較了
3.最后使用git commit
提交一次奶陈,這時(shí)候a,b,c內(nèi)容都一樣,都包含two
。
結(jié)論驰怎,如圖看出,沒有變化春霍,說明a,b,c內(nèi)容一樣
根據(jù)上面的實(shí)例再一次證明了如下觀點(diǎn):
git diff 比較工作區(qū)跟暫存區(qū)
git diff --cached 比較暫存區(qū)跟HEAD
git diff HEAD 比較工作區(qū)跟HEAD
證明git reset跟 git checkout結(jié)論
例子砸西,默認(rèn)新建一個(gè)readme.txt
,里面輸入內(nèi)容one
然后add并且commit
一次址儒,這時(shí)候a,b,c內(nèi)容都是one
1.修改readme.txt
芹枷,新增內(nèi)容two
,執(zhí)行git add readme.txt
操作莲趣,這時(shí)候a ,b內(nèi)容都多了two
,c還是只有one
.
執(zhí)行git reset HEAD -- readme.txt
命令后鸳慈,c覆蓋b,這時(shí)候b內(nèi)容也變成只有one
了,使用git diff readme.txt
命令可以看到喧伞,有內(nèi)容修改走芋,a跟b內(nèi)容不一樣。
2.此時(shí)a內(nèi)容有two,b和c都只有one潘鲫,執(zhí)行git checkout -- readme.txt
后翁逞,b覆蓋a,此時(shí)a,b,c都是one。執(zhí)行git diff readme.txt
命令可以看到溉仑,沒有改變挖函。
3.此時(shí)a,b,c都只有one
,修改一下浊竟,添加內(nèi)容two
怨喘,執(zhí)行git add readme.txt
和git commit -m "two"
.再修改一次readme.txt
,添加內(nèi)容three
,然后會(huì)執(zhí)行git add readme.txt
津畸,此時(shí)a跟b都包含three,而c只包含one跟two必怜。執(zhí)行git checkout HEAD readme.txt
后肉拓,c覆蓋a和b,a,b里面內(nèi)容都只有one跟two。分別使用命令git diff --cached
和git diff HEAD
來(lái)查看b跟c梳庆,a跟c的比對(duì)暖途,發(fā)現(xiàn)都一樣。
根據(jù)上面的實(shí)例再一次證明了如下觀點(diǎn):
git reset HEAD HEAD覆蓋暫存區(qū)
git checkout -- <file> 暫存區(qū)覆蓋工作區(qū)
git checkout HEAD <file> HEAD覆蓋暫存區(qū)和工作區(qū)
證明git rm 結(jié)論
默認(rèn)新建一個(gè)readme.txt
靠益,里面輸入內(nèi)容one
丧肴,然后使用git add readme.txt
命令。
1.執(zhí)行g(shù)it rm readme.txt命令胧后,發(fā)現(xiàn)文件被刪除了芋浮。
2.再新建一個(gè)一個(gè)readme.txt
,里面輸入內(nèi)容 one壳快,然后使用git add readme.txt
命令纸巷。執(zhí)行git rm --cached readme.txt
命令,發(fā)現(xiàn)文件內(nèi)readme.txt
還在眶痰,然后執(zhí)行git status
命令瘤旨,發(fā)現(xiàn)是Untracked
狀態(tài),也就是未add
竖伯,這就說明暫存區(qū)被刪除了存哲。
根據(jù)上面的實(shí)例再一次證明了如下觀點(diǎn):
git rm file 會(huì)將文件從緩存區(qū)和你的硬盤中(工作區(qū))刪除
git rm --cached 只刪除暫存區(qū),不刪除工作區(qū)
rm file 只刪除工作區(qū)
總結(jié)
暫存區(qū)的原理需要大家重復(fù)的加深了解七婴,基礎(chǔ)打牢了后面學(xué)起來(lái)就輕松很多祟偷,上面幾個(gè)例子都自己驗(yàn)證一遍,加深印象打厘。
一直覺得自己寫的不是技術(shù)修肠,而是情懷,一篇篇文章是自己這一路走來(lái)的痕跡户盯∏妒靠專業(yè)技能的成功是最具可復(fù)制性的,希望我的這條路能讓你少走彎路莽鸭,希望我能幫你抹去知識(shí)的蒙塵吗伤,希望我能幫你理清知識(shí)的脈絡(luò),希望未來(lái)技術(shù)之巔上有你也有我硫眨。