Git實用教程6:回到過去(回滾相關命令)

本節主要知識點:


在這裏插入圖片描述
回滾相關命令

  • git add 命令用於把工作目錄的文件放入暫存區域
  • git commit 命令用於把暫存區域的文件提交到 Git 倉庫
  • git reset 命令用於把 Git 倉庫的文件還原到暫存區域
  • git checkout 命令用於把暫存區域的文件還原到工作目錄

reset 回滾快照三步曲

  1. 移動 HEAD 的指向(–soft)
  2. 將快照回滾到暫存區域([–mixed],默認)
  3. 將暫存區域還原到工作目錄(–hard)

回滾指定快照

在命令行中將路徑切換至文件夾中,然後使用命令git reset + 具體的快照 ID(一般5位就行)'

回滾個別文件

在命令行中將路徑切換至文件夾中,然後使用命令git reset 快照 文件名/路徑 '

reset 不僅是一個“復古”的命令,它不僅可以回到過去,還可以去到“未來”。不僅可以往回滾,還可以往前滾!

失去了以前版本的ID

在命令行中將路徑切換至文件夾中,然後使用命令git reflog'




上一講無意中接觸到了兩個有關回退的命令:resetcheckout
在這裏插入圖片描述
現在幾個命令應該相當清晰了:

  • git add 命令用於把工作目錄的文件放入暫存區域
  • git commit 命令用於把暫存區域的文件提交到 Git 倉庫
  • git reset 命令用於把 Git 倉庫的文件還原到暫存區域
  • git checkout 命令用於把暫存區域的文件還原到工作目錄

前邊兩個命令我有信心你已經相當熟悉了,但後邊兩個千萬別說你已懂,因爲它們是 Git 裏邊最複雜的命令(它們的功能可不止上邊文字描述的這麼簡單

先給大家重點講解 reset 命令,checkout 命令在分支管理中再細講。

先執行 git log 命令查看歷史提交:

在這裏插入圖片描述
這裏記錄了我們之前的 3 次提交(排序是按時間從近到遠的),Author 後邊是提交者,Date 後邊是提交日期,下邊是當次提交的說明。那……草黃色的那個 commit +“亂碼”是 Git 爲每次提交計算出來的 ID,它其實一個完整的 SHA-1 校驗和(儘管你的文件內容可能跟我的完全一致,但這個值卻不一樣,這是因爲賬號、時間不同而導致),在任何時候都是唯一的,通過這個 ID,你就可以找到對應的那個版本。

根據 log 記錄,現在我們將 Git 倉庫如果可視化,應該是這樣子:
在這裏插入圖片描述

回滾快照


注:快照即提交的版本,每個版本我們稱之爲一個快照。

現在我們利用 reset 命令回滾快照,並看看 Git 倉庫和三棵樹分別發生了什麼。

執行 it reset HEAD~ 命令:

注:HEAD 表示最新提交的快照(31f46),而 HEAD~ 表示 HEAD 的上一個快照(d19e3)
在這裏插入圖片描述
然後執行 git status 命令查看現在的狀態:

在這裏插入圖片描述
現在我們的快照(d19e3)回滾到 第二棵樹(暫存區域)

有些朋友可能會持不同意見:不應該是回滾到第一棵樹(工作目錄)嗎?你看,Git 不是寫得很清楚嗎 -> Changes not staged for commit,它還好心提醒我們使用 add 命令將修改添加到暫存區域丫!

其實真相是這樣的:我們執行 git reset HEAD~ 命令之後,快照(d19e3)回滾到暫存區域,此時工作目錄裏存放的卻是最新的文件(31f46)。由於 Git 會跟蹤文件的變化,所以執行 git status 命令時,git 發現工作目錄中的文件比暫存區域的要新(對比日期),所以纔有這樣的提示……

好了,現在執行完 git reset HEAD~ 命令之後,Git 倉庫應該是這樣子:
在這裏插入圖片描述
三棵樹現在應該是下面醬紫:
在這裏插入圖片描述
這裏有一點要補充的:HEAD~ 表示 HEAD 的上一個快照(d19e3),HEAD~~(00c29)則表示 HEAD 的上上一個快照,如果希望表示上 上 上 上 上 上 上 上 上 上一個快照(數了一下,這裏有 10 個“上” ),那麼可以直接用 HEAD~10 來表示。

git reset HEAD~ 命令其實是 git reset --mixed HEAD~ 的縮寫,因爲 --mixed 選項是默認的,所以我們可以偷懶。

我們發現,git reset HEAD~ 命令其實影響了兩棵樹:首先是移動 HEAD 的指向,將其指向上一個快照(HEAD~);然後再將該位置的快照回滾到暫存區域。

爲了靈活地操縱這三棵樹,Git 還爲 reset 命令安排了 --soft 和 --hard 選項

–soft 選項


加上 --soft 選項的結果是使得 reset 變“軟”了,也就沒有原來那麼持久……

So, git reset --soft HEAD~ 命令就相當於只移動 HEAD 的指向,但並不會將快照回滾到暫存區域。

這個選項有什麼作用呢?

事實它就是相當於撤消了上一次的提交(commit)。

一不小心提交了,後悔了,那麼你就執行 git reset --soft HEAD~ 命令即可(此時執行 git log 命令,也不會再看到已經撤消了的那個提交)。

–hard 選項


加上 --hard 選項的結果是使得 reset 變“硬”……

你猜的不錯,加上 --hard 選項,reset 不僅移動 HEAD 的指向,將快照回滾動到暫存區域,它還將暫存區域的文件還原到工作目錄。

來,上點圖吧!

剛纔執行完 git reset HEAD~ 命令後,Git 倉庫裏的數據是這樣:
在這裏插入圖片描述
三棵樹是這樣:
在這裏插入圖片描述
那麼在這種狀態下,我再執行 git reset --hard HEAD~ 命令:
在這裏插入圖片描述
Git 倉庫中就剩下最後一個快照了:
在這裏插入圖片描述
還原案發現場,Git 倉庫現在應該是這樣:
在這裏插入圖片描述
而三棵樹現在應該都被迴歸到第一個版本(00c2929):
在這裏插入圖片描述
不信?自己瞧瞧你的文件夾:
在這裏插入圖片描述
最後總結一下:reset 回滾快照三部曲

  1. 移動 HEAD 的指向(–soft)

  2. 將快照回滾到暫存區域([–mixed],默認)

  3. 將暫存區域還原到工作目錄(–hard)

回滾指定快照

如果快照比較多,你又懶得去數有多少個“上”,那麼你可以通過指定具體的快照 ID 來回滾該快照。

比如 git reset 00c2929
如上,你不必把辣麼長的 ID 號都給輸入進去,一般只要輸入前幾位(5 位或以上吧)就可以了。

回滾個別文件

reset 不僅可以回滾指定快照,還可以回滾個別文件。

命令格式爲 git reset 快照 文件名/路徑

這樣,它就會將忽略移動 HEAD 的指向這一步(因爲你只是回滾快照的部分內容,並不是整個快照,所以 HEAD 的指向不應該發生改變),直接將指定快照的指定文件回滾到暫存區域。

不僅可以往回滾,還可以往前滾!

這裏需要強調的是:reset 不僅是一個“復古”的命令,它不僅可以回到過去,還可以去到“未來”。

唯一的一個前提條件是:你需要知道指定快照的 ID 號。

現在執行 git log 命令只剩下一個最原始的提交了:

在這裏插入圖片描述
但是將命令行窗口向上拉,我們可以喵到之前提交的幾個版本 ID 號
在這裏插入圖片描述
所以我們可以執行 git reset --hard 31f46be 命令:
在這裏插入圖片描述
再次執行 git log 命令:
在這裏插入圖片描述
我們又回到了最新的版本!

是的,我們就這樣在歷史的長河裏滾來滾去……

但是……故事還沒完,如果某天你 reset --hard 將工作目錄回滾到了某個版本,但特麼的隔天你就後悔了(有封寫給小花的情書也放裏邊)!此時命令行窗口早已關閉,你又沒用小本本把每次 commit 的 ID 號給記下來,這可腫麼辦纔好?

reflog 命令可以拯救你!

執行 git reflog 命令,告訴我,你看到了什麼:
在這裏插入圖片描述
Git 偷偷記錄下了你每一次的操作(無恥小人),第一列就是每次執行完命令,HEAD 指向的版本 ID 號啦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章