← 上一章:【狀況題】剛才的 Commit 後悔了,想要拆掉重做… 下一章:【冷知識】HEAD 是什麼東西? →


【狀況題】不小心使用 hard 模式 Reset 了某個 Commit,救得回來嗎?

借用一下上個章節的例子:

$ git log --oneline
e12d8ef (HEAD -> master) add database.yml in config folder
85e7e30 add hello
657fce7 add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

上面共計有六次 Commit。首先要先建立一個觀念,不管是用什麼模式進行 Reset,Commit 就是 Commit,並不會因為你 Reset 它然後就消失了。假設我們先用預設模式的 reset 指令倒退 2 步:

$ git reset HEAD~2

這時候 Commit 看起來就會少兩個,同時拆出來的檔案會被放置在工作目錄:

$ git log --oneline
657fce7 (HEAD -> master) add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

如果想要退回剛剛 Reset 的這個步驟,只要 Reset 回到一開始那個 Commit 的 SHA-1 e12d8ef 就行了:

$ git reset e12d8ef --hard

剛剛看起來拆掉的 Commit 就又接回來了。在這裡使用 --hard 參數可以強迫放棄 Reset 之後修改的檔案。

使用 Reflog

如果一開始沒有記下來 Commit 的 SHA-1 值也沒關係,Git 裡有個 reflog 指令有保留一些紀錄。再次借用上個章節的例子,但這次我改用 --hard 模式來進行 reset:

$ git reset HEAD~2 --hard
HEAD is now at 657fce7 add container

不僅 Commit 看起來不見了,檔案也消失了。接著可使用 reflog 指令來看一下紀錄:

$ git reflog
657fce7 (HEAD -> master) HEAD@{0}: reset: moving to HEAD~2
e12d8ef (origin/master, origin/HEAD, cat) HEAD@{1}: checkout: moving from cat to master
e12d8ef (origin/master, origin/HEAD, cat) HEAD@{2}: checkout: moving from master to cat

HEAD 有移動的時候(例如切換分支或是 reset 都會造成 HEAD 移動),Git 就會在 Reflog 裡記上一筆。從上面的這三筆記錄看起來大概可以猜得出來最近三次 HEAD 的移動,而最後一次的動作就是 Reset。所以如果想要取消這次的 Reset,就是「Reset 到它 Reset 前的那個 Commit」(很像饒口令)。在這個例子就是 e12d8ef,所以只要這樣:

$ git reset e12d8ef --hard

就可以把剛剛 hard reset 的東西再次撿回來了。

小提示

git log 如果加上 -g 參數,也可以看到 Reflog 喔!


← 上一章:【狀況題】剛才的 Commit 後悔了,想要拆掉重做… 下一章:【冷知識】HEAD 是什麼東西? →

Comments