首先,我們先弄清楚幾個定義:
- HEAD(頭)
HEAD 是當(dāng)前分支引用的指針,它總是指向該分支上的最后一次提交。 這表示 HEAD 將是下一次提交的父結(jié)點(diǎn)。 通常,理解 HEAD 的最簡方式,就是將它看做 你的上一次提交 的快照 - Index (索引)
也可以被認(rèn)為是staging area(暫存區(qū)),是一堆將在下一次commit中提交的文件,提交之后,它就是HEAD的父節(jié)點(diǎn)(git add添加的文件) - working copy (工作副本)
當(dāng)前工作目錄下的文件(一般指,有修改,沒有g(shù)it add,沒有g(shù)it commit的文件)
Flow (流程如下)
- 當(dāng)你第一次checkout一個新的分支,HEAD指向該分支上最近一次commit。它和index和working copy是一樣一樣的。
- 當(dāng)你修改了一個文件,Git注意到了會說“哦,有些東西被改了”,你的working copy不再和index和HEAD相同了,所以當(dāng)文件有改動,它會標(biāo)記這些文件。
- 然后,你執(zhí)行g(shù)it add命令,這條命令會將上面修改的文件緩存在index中,Git又說了“哦,你的working copy和index相同了,而他們倆和HEAD不同了”。
- 當(dāng)你執(zhí)行g(shù)it commit,Git創(chuàng)建了一個新的commit,HEAD這時指向這個新的commit,此時,HEAD & index & working copy又相同了。
reset(重置)
-
但是,我們寫代碼,總有犯錯的時候,如果不滿意這次修改,想要回退到上一次提交,怎么辦? 這個時候,有幾個命令可以幫助到我們!
git reset --hard
git reset --soft
git reset --mixed
-
git reset --hard
這個命令非常危險,是git中,少有幾個會丟失信息的操作,會直接刪除掉目標(biāo)HEAD之后所有的操作,且工作去和暫存區(qū)都會修改
看下邊的例子,這是修改前的遠(yuǎn)程倉庫,和修改前的本地倉庫
image.png
image.png
然后我在本地倉庫新建一個b.md, 并git add 到暫存區(qū),但是并沒有提交
image.png
然后執(zhí)行 git reset -- hard 命令 ,執(zhí)行命令后,工作區(qū),暫存區(qū),和遠(yuǎn)程庫又保持一致了,回到了上一次commit 的狀態(tài)
image.png git reset --soft
soft參數(shù),告訴Git重置HEAD到另外一個commit,但也到此為止。如果你指定--soft參數(shù),Git將停止在那里而什么也不會根本變化。這意味著index,working copy都不會做任何變化,所有的在original HEAD和你重置到的那個commit之間的所有變更集都放在stage(index)區(qū)域中。git reset --mixed(default)
mixed是reset的默認(rèn)參數(shù),也就是當(dāng)你不指定任何參數(shù)時的參數(shù)。它將重置HEAD到另外一個commit,并且重置index以便和HEAD相匹配,但是也到此為止。working copy不會被更改。所有該branch上從original HEAD(commit)到你重置到的那個commit之間的所有變更將作為local modifications保存在working area中,(被標(biāo)示為local modification or untracked via git status),但是并未staged的狀態(tài),你可以重新檢視然后再做修改和commit
git revet
git revert 撤銷 某次操作,此次操作之前和之后的commit和history都會保留,并且把這次撤銷
- git revert HEAD 撤銷前一次 commit
- git revert HEAD^ 撤銷前前一次 commit
- git revert commit (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)撤銷指定的版本,撤銷也會作為一次提交進(jìn)行保存。
- git revert是提交一個新的版本,將需要revert的版本的內(nèi)容再反向修改回去,版本會遞增,不影響之前提交的內(nèi)容
git revet 和 git reset的區(qū)別
- git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit。
- 在回滾這一操作上看,效果差不多。但是在日后繼續(xù)merge以前的老版本時有區(qū)別。因為git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch時,導(dǎo)致這部分改變不會再次出現(xiàn),但是git reset是之間把某些commit在某個branch上刪除,因而和老的branch再次merge時,這些被回滾的commit應(yīng)該還會被引入。
- git reset 是把HEAD向后移動了一下,而git revert是HEAD繼續(xù)前進(jìn),只是新的commit的內(nèi)容和要revert的內(nèi)容正好相反,能夠抵消要被revert的內(nèi)容。



