這篇文章主要講解了“git reset的用法是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“git reset的用法是什么”吧!
成都創(chuàng)新互聯(lián)公司是由多位在大型網(wǎng)絡(luò)公司、廣告設(shè)計(jì)公司的優(yōu)秀設(shè)計(jì)人員和策劃人員組成的一個(gè)具有豐富經(jīng)驗(yàn)的團(tuán)隊(duì),其中包括網(wǎng)站策劃、網(wǎng)頁(yè)美工、網(wǎng)站程序員、網(wǎng)頁(yè)設(shè)計(jì)師、平面廣告設(shè)計(jì)師、網(wǎng)絡(luò)營(yíng)銷(xiāo)人員及形象策劃。承接:網(wǎng)站制作、做網(wǎng)站、網(wǎng)站改版、網(wǎng)頁(yè)設(shè)計(jì)制作、網(wǎng)站建設(shè)與維護(hù)、網(wǎng)絡(luò)推廣、數(shù)據(jù)庫(kù)開(kāi)發(fā),以高性?xún)r(jià)比制作企業(yè)網(wǎng)站、行業(yè)門(mén)戶(hù)平臺(tái)等全方位的服務(wù)。
一、可以將git簡(jiǎn)單的分為三個(gè)區(qū)域
1、工作區(qū)(working directory)
2、暫緩區(qū)(stage index)
3、歷史記錄區(qū)(history)
其中g(shù)it add files 把當(dāng)前工作目錄中的文件放入暫存區(qū)域 ,這其實(shí)做了兩件事:
1、將本地文件的時(shí)間戳、長(zhǎng)度,當(dāng)前文檔對(duì)象的id等信息保存到一個(gè)樹(shù)形目錄中去(index,即平時(shí)說(shuō)的暫存區(qū))
2、將本地文件的內(nèi)容做快照并保存到Git 的對(duì)象庫(kù) 。
綜上2點(diǎn)來(lái)說(shuō),暫存區(qū)實(shí)際上就是一個(gè)包含文件索引的目錄樹(shù),像是一個(gè)虛擬的工作區(qū)。在這個(gè)虛擬工作區(qū)的目錄樹(shù)中,記錄了文件名、文件的狀態(tài)信息(時(shí)間戳、文件長(zhǎng)度等),文件的內(nèi)容并不存儲(chǔ)其中,而是保存在 Git 對(duì)象庫(kù)(.git/objects)中,文件索引建立了文件和對(duì)象庫(kù)中對(duì)象實(shí)體之間的對(duì)應(yīng)。
我們可以看到部分 Git 命令是如何影響工作區(qū)和暫存區(qū)(stage, index)的:
左側(cè)為工作區(qū),右側(cè)為版本庫(kù)。在版本庫(kù)中標(biāo)記為 "index" 的區(qū)域是暫存區(qū)(stage, index),標(biāo)記為 "master" 的是 master 分支所代表的目錄樹(shù)。
我們可以看出此時(shí) "HEAD" 實(shí)際是指向 master 分支的一個(gè)“游標(biāo)”。所以圖示的命令中出現(xiàn) HEAD 的地方可以用 master 來(lái)替換。
objects 標(biāo)識(shí)的區(qū)域?yàn)?Git 的對(duì)象庫(kù),實(shí)際位于 ".git/objects"目錄下
當(dāng)對(duì)工作區(qū)修改(或新增)的文件執(zhí)行 "git add" 命令時(shí),暫存區(qū)的目錄樹(shù)被更新,同時(shí)工作區(qū)修改(或新增)的文件內(nèi)容被寫(xiě)入到對(duì)象庫(kù)中的一個(gè)新的對(duì)象中,而該對(duì)象的ID 被記錄在暫存區(qū)的文件索引中
當(dāng)執(zhí)行提交操作(git commit)時(shí),暫存區(qū)的目錄樹(shù)寫(xiě)到版本庫(kù)(對(duì)象庫(kù))中,master 分支會(huì)做相應(yīng)的更新。即 master 指向的目錄樹(shù)就是提交時(shí)暫存區(qū)的目錄樹(shù) 。
當(dāng)執(zhí)行 "git status" 命令掃描工作區(qū)改動(dòng)的時(shí)候,先依據(jù) .git/index 文件中記錄的(工作區(qū)跟蹤文件的)時(shí)間戳、長(zhǎng)度等信息判斷工作區(qū)文件是否改變。如果工作區(qū)的文件時(shí)間戳改變,說(shuō)明文件的內(nèi)容可能被改變了,需要打開(kāi)文件,讀取文件內(nèi)容,和更改前的原始文件相比較(本地文件和與之對(duì)應(yīng)的object庫(kù)中的文件的內(nèi)容進(jìn)行對(duì)比),判斷文件內(nèi)容是否被更改。如果文件內(nèi)容沒(méi)有改變,則將該文件新的時(shí)間戳記錄到 .git/index 文件中。因?yàn)榕袛辔募欠窀?,使用時(shí)間戳、文件長(zhǎng)度等信息進(jìn)行比較要比通過(guò)文件內(nèi)容比較要快的多,所以 Git 這樣的實(shí)現(xiàn)方式可以讓工作區(qū)狀態(tài)掃描更快速的執(zhí)行,這也是 Git 高效的因素之一。
git diff files用來(lái)進(jìn)行具體文件的變動(dòng)對(duì)比,通常用來(lái)進(jìn)行工作區(qū)與暫存區(qū)之間的對(duì)比,實(shí)質(zhì)上是用 git objects 庫(kù)中的快照與工作區(qū)文件的內(nèi)容的對(duì)比。
另外,Git中提供了幾個(gè)相關(guān)的撤銷(xiāo)操作的命令,如git reset、git revert、git checkout,這幾者之間的用法各有不同。
二、git reset的用法
從上圖可知:git reset -- files 用來(lái)撤銷(xiāo)最后一次的git add files(因?yàn)槊縢it add file一次,暫存區(qū)的文件都會(huì)被更改一次),你也可以用git reset 撤銷(xiāo)所有暫存區(qū)域文件。
另外:
一、git reset的用法:git reset + commit號(hào)
1、git reset命令后面需要加2種參數(shù):"--hard"和"--soft",如果不加,默認(rèn)情況下是"--soft"。
2、--soft表示該條commit號(hào)之后(時(shí)間作為參考點(diǎn))的所有commit的修改都會(huì)退回到git緩沖區(qū)中。所以使用git status命令可以在緩沖區(qū)中看到這些修改。
3、"--hard"則表示緩沖區(qū)中不會(huì)存儲(chǔ)這些修改,git會(huì)直接丟棄這部分內(nèi)容,但需要注意的一個(gè)問(wèn)題是:這樣的重置是直接在本地的修改,無(wú)法提交到遠(yuǎn)程服務(wù)器,如果直接丟棄的內(nèi)容已經(jīng)被推到遠(yuǎn)程服務(wù)器上了,則會(huì)造成本地和服務(wù)器無(wú)法同步的問(wèn)題,即git reset --hard只能針對(duì)本地操作,不能針對(duì)遠(yuǎn)程服務(wù)器進(jìn)行同樣操作。如果從本地刪掉的內(nèi)容沒(méi)有推到服務(wù)器上,則不會(huì)有副作用,如果被推到服務(wù)器,則下次本地和服務(wù)器進(jìn)行同步時(shí),這
部分刪掉的內(nèi)容仍然會(huì)回來(lái)。
(其實(shí)這個(gè)問(wèn)題則可以很好的被git revert 命令解決,使用git revert + commit號(hào),該命令撤銷(xiāo)對(duì)某個(gè)commit的提交,這一撤銷(xiāo)動(dòng)作會(huì)作為一個(gè)新的修改存儲(chǔ)起來(lái),這樣,當(dāng)你和服務(wù)器同步時(shí),就不會(huì)產(chǎn)生什么副作用。)
其實(shí)在merge的時(shí)候,也有可能會(huì)用到git reset.
如果我們當(dāng)前使用git pull的時(shí)候,可能會(huì)出現(xiàn)merge沖突,在沖突狀態(tài)下,需要解決沖突的文件會(huì)從index暫存區(qū)打回到工作區(qū)。
如果有沖突的時(shí)候,一般用如下步驟解決沖突:
1、用工具或者手工解決沖突
2、git add 命令來(lái)表明沖突已經(jīng)解決。
3、再次commit已解決沖突的文件。
這當(dāng)中,可以使用git reset --hard ORIG_HEAD用來(lái)撤銷(xiāo)已經(jīng)commit的merge.
使用git reset --hard HEAD 用來(lái)撤銷(xiāo)還沒(méi)commit 的merge,其實(shí)原理就是放棄index和工作區(qū)的改動(dòng)。
也可以使用git reset --merge ORIG_HEAD,注意其中的--hard 換成了 --merge,這樣就可以避免在回滾時(shí)清除working tree。
三、git checkout的用法
從上圖可知,git checkout -- files 把文件從暫存區(qū)域復(fù)制到工作目錄,用來(lái)丟棄本地修改。 需要另外注意的是:
1、當(dāng)執(zhí)行 "git rm --cached
2、當(dāng)執(zhí)行 "git checkout ." 或者 "git checkout --
3、當(dāng)執(zhí)行 "git checkout HEAD ." 或者 "git checkout HEAD
四、git revert的用法
git revert 也是撤銷(xiāo)命令,區(qū)別在于reset是指向原地或者向前移動(dòng)指針,git revert是創(chuàng)建一個(gè)commit來(lái)覆蓋當(dāng)前的commit,指針向后移動(dòng)。
那么兩者的具體區(qū)別有:
1)git revert 是撤銷(xiāo)某次操作,此次操作之前的commit都會(huì)被保留,而git reset 是撤銷(xiāo)某次提交,但是此次之后的修改都會(huì)被退回到暫存區(qū)中。
具體一個(gè)例子,假設(shè)有三個(gè)commit(commit1,commit2,commit3),使用 git status:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
當(dāng)執(zhí)行g(shù)it revert HEAD~1時(shí)(撤銷(xiāo)倒數(shù)第二個(gè)操作),第二個(gè)操作即commit2這個(gè)操作被撤銷(xiāo)了,使用git log可以看到:
commit1:add test1.c
commit3:add test3.c
由于git revert不會(huì)回退到暫存區(qū)中,所以使用git status 沒(méi)有任何變化
如果換做執(zhí)行g(shù)it reset --soft(默認(rèn)) HEAD~1后,運(yùn)行g(shù)it log可以看到
commit2: add test2.c
commit1: add test1.c
運(yùn)行g(shù)it status,可以看到test3.c處于暫存區(qū)了,準(zhǔn)備提交。
但如果換做執(zhí)行g(shù)it revert后,
顯示:HEAD is now at commit2,運(yùn)行g(shù)it log可以看到
commit2: add test2.c
commit1: add test1.c
運(yùn)行g(shù)it status, 則沒(méi)有任何變化
所以,git revert與git reset最大的不同是,git revert 僅僅是撤銷(xiāo)某次提交,而git reset會(huì)將撤銷(xiāo)點(diǎn)之后的操作
都回退到暫存區(qū)中。
1、git revert是用一次新的commit來(lái)回滾之前的commit,git reset是直接刪除指定的commit。
2、在回滾這一操作上看,效果差不多。但是在日后繼續(xù)merge以前的老版本時(shí)有區(qū)別。
因?yàn)間it revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch時(shí),導(dǎo)致這部分改變不會(huì)再次出現(xiàn),但是git reset是之間把某些commit在某個(gè)branch上刪除,因而和老的branch再次merge時(shí),這些被回滾的commit應(yīng)該還會(huì)被引入。
3、git reset 是把HEAD向后移動(dòng)了一下,而git revert是HEAD繼續(xù)前進(jìn),只是新的commit的內(nèi)容和要revert的內(nèi)容正好相反,能夠抵消要被revert的內(nèi)容。
六、不得不提的git的其它刪除命令(類(lèi)似于Linux的命令):
git rm --cached readme.txt 只從緩存區(qū)中刪除readme.txt,保留物理文件
git rm readme.txt 不但從緩存區(qū)中刪除,同時(shí)刪除物理文件
git mv a.txt b.txt 把a(bǔ).txt改名為b.txt
綜上所以我們有時(shí)如果是想撤銷(xiāo)對(duì)單個(gè)文件的更改:
<->、如果已經(jīng)用add命令把文件加入stage暫存區(qū)了:
1、就先需要從stage暫存區(qū)中撤銷(xiāo):
"git reset HEAD
2、然后再?gòu)墓ぷ鲄^(qū)撤銷(xiāo),即將暫存區(qū)的文件替換工作區(qū)當(dāng)前的文件
"git checkout --
如:git checkout a.txt 撤銷(xiāo)a.txt的變動(dòng)(工作區(qū)上的文件)
如果是多個(gè)文件:git chenkout .
<二>、如果已經(jīng)commit了,則需要
1、使用git commit --amend來(lái)進(jìn)行修改,這個(gè)只能修改最近一次的,也就是用一個(gè)新的提交來(lái)覆蓋上一次的提交。因此如果push以后再做這個(gè)動(dòng)作就會(huì)有危險(xiǎn)。
2、git reset --hard HEAD 放棄工作區(qū)和index的改動(dòng),HEAD指針仍然指向當(dāng)前的commit.(參照第一幅圖)
這條命令同時(shí)還可以用來(lái)撤銷(xiāo)還沒(méi)commit的merge,其實(shí)原理就是放棄index暫存區(qū)和工作區(qū)的改動(dòng),因?yàn)闆](méi)commit的改動(dòng)只存在于index暫存區(qū)和工作區(qū)中。
而git reset --hard HEAD^ 用來(lái)撤銷(xiāo)已經(jīng)commit的內(nèi)容(等價(jià)于 git reset --hard HEAD~1) 。原理就是放棄工作區(qū)和index的改動(dòng),同時(shí)HEAD指針指向前一個(gè)commit對(duì)象。
感謝各位的閱讀,以上就是“git reset的用法是什么”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)git reset的用法是什么這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!