【Git】Git reset/revert的應用

weixin_34148340發表於2017-07-25

課下來自己動手試試git的命令

主要嘗試及記錄

git reset --hard
git reset --soft
git revert

以上3個命令的具體作用及區別,這些命令主要用於撤銷修改,但又各有些小區別

嘗試準備

首先,為了製造合適的測試環境,我選擇重新初始化一個本地git倉庫來嘗試,因為不涉及到push到遠端倉庫,所以也就不需要遠端倉庫了,這個本地倉庫純用於測試

瞭解HEAD

為了更加方便理解命令的作用不同,我們還需要了解一個HEAD的概念
HEAD簡單來說,指的就是當前當前分支的最近一次提交後的版本,也就是說,HEAD代表的是最新的版本,根據這個概念,我們還可以知道HEAD就是指上一個版本,同理HEAD就是再上一個版本,因為(英文符號shift+6)不太方便,我們也可以以HEAD~x來表示距離最新版本的之前幾個版本

建立本地倉庫並新增檔案

6663055-8095dfa87a518a44.png
建立本地git倉庫並建立提交a.md檔案

橫向對比

準備工作做好後,我們就來試試幾個命令
首先,我們先對a.md進行3次編輯及提交以產生3個版本記錄

6663055-e083b2c436464c5f.png
對a.md進行3次編輯並提交
6663055-5aa44649279c7ded.png
經過3次編輯提交的a.md

這裡引入了一個log的新用法git log --oneline,這個log命令能夠讓我們相對直觀的看到最近的版本記錄並標識出提交版本號
在這個情況下,我們的工作區和暫存區都是乾淨的,我們不想要第三次提交了,我們來試試三個命令的不同

git reset --hard

6663055-57a0c6d96db5d88d.png
使用git reset --hard HEAD^

這時候我們看到操作成功,我們來看一下對於檔案產生了什麼作用,首先檢視a.md,並檢視狀態

6663055-70420115da3adef3.png
git reset --hard HEAD^之後的a.md

6663055-4938f54dd836f966.png
reset --hard之後的status

我們能看到,reset --hard命令不僅將修改的檔案變為了第二次提交的狀態,並且不用我們再次commit
這時候我們再log --oneline看一下

6663055-0b2f37b7cae35e05.png
git log --oneline

我們看到,我們的第三次提交記錄被抹去了,也就是說,reset --hard的作用差不多是完全重置到某個版本並且銷燬提交記錄,本能的感覺到這個操作比較危險,我們來看一下歷史的log

6663055-8e69c3bf338cb550.png
git reflog

可以看到我們當前的HEAD確實處於了第二次編輯提交的狀態,按下不表,接著試試--soft

git reset --soft

之前的記錄已經被毀了,但是通過查閱資料,我們是可以恢復的

6663055-a4f20335a75a7b1c.png
git reflog及git reset --hard {版本號}

我們從git reflog中可以看到,第三次編輯並提交的版本號為0379f9d,所以我們用--hard+版本號引數的命令回到三次編輯並提交的狀態,接著嘗試--soft
同樣的,我們不想要第三次提交,希望回退到第二次提交

6663055-ee965dfa7f1ab8f0.png
git reset --soft HEAD^

看到操作成功了, 但是並沒有什麼提示,那我們看看git狀態和a.md的狀態吧

6663055-d7adce57d18452e5.png
git status
6663055-22433354b3baf0f7.png
a.md

我們看到了,--soft命令,僅僅是把我們的第三次‘commit’的操作給撤銷了,a.md處於第三次編輯完成、add完成,但未提交的狀態
簡單來看,也就是說--soft命令是撤銷指定版本內容的那一次commit,其他的東西都不改變,接著試試revert命令

git revert

我們再次使用git reflog查詢版本號並回到三次編輯提交的狀態,同樣,還是不希望保留第三次編輯提交

6663055-6c4fd19014e2a3d1.png
git reset --hard

然後我們試試revert

6663055-ae2d4ba91bd4206e.png
git revert

在回到3次編輯提交的版本後,我進行了一次log查詢及狀態查詢,狀態顯示沒有待提交的的東西,但是在進行revert想回到第二次編輯的狀態時,提示失敗,失敗後再檢視狀態看到了a.md的unmerged的提示,講道理,我到這裡已經有點懵逼了,就按照提示,我再進行了一次commit,併產生了一條“由於revert失敗,提交一次第三次編輯的a.md”的修改版本記錄,這一點有點摸不到頭腦,回頭還是會問一下老師,總之,我們繼續
我們還會是向回到第二次編輯狀態,嘗試git revert

6663055-dc37394f4768996c.png
git revert

我們看到,操作成功了,並且自動開啟了vim讓我們編輯本次變動的提交資訊,我們直接儲存退出
操作成功後,檢視status並檢視a.md的狀態

6663055-d0aa94ad21d01fc7.png
status及log
6663055-20a110670f9538e3.png
revert後的a.md

我們發現a.md被改變了,改成了一個奇怪的樣子,到這裡我已經完全懵逼了,,所以我覺得從頭來一次純淨版本的revert
重新建立b.md並編輯提交3次

6663055-e4f93c7140fbfa04.png
新建b.md

我們來直接試試revert到第二次編輯

6663055-ebb7ddae2ddb73ba.png
git revert
6663055-b9d65b2dc02e3b5b.png
revert後的b.md

我們看到這次的revert操作比較成功,但是由於目標是第二次編輯提交的版本,所以在revert的時候接連彈出了兩個revert的commit資訊輸入框,完成後的log如下圖,生成了兩個新log,一個是回退到第三次編輯提交、一個是回退到第二次編輯提交
從這裡有兩步我們就可以看出,revert命令會講檔案修改為目標版本的上一個版本,也就是撤銷了修改及add、commit

小結

其實到這裡,我還是有點懵逼的,但是基本的效果大概有了一定了解

git reset --hard

毀滅性質的直接將版本重置到指定版本的狀態,直接刪除指定版本的commit內容,同時如果本地有修改內容話也會丟失
事了拂衣去,並不會留下通常能查到的版本記錄,僅能在git reflog查詢

git reset --soft

只告訴Git將其他的commit重置到HEAD,並不影響工作區檔案
同樣不會保留常規log

git revert

這其實算是一個進度往前走的逆向提交,也就是說HEAD版本及提交記錄將會繼續前進,只是新的commit的內容和要revert的內容正好相反,能夠抵消要被revert的內容。

大概就是這麼多淺顯理解,還有很多不足,希望能夠在今後的常規使用中逐漸加深理解!

相關文章