Git 的 4 個階段的撤銷更改

2022-05-02 16:09:14 字數 3356 閱讀 1153

雖然git誕生距今已有12年之久,網上各種關於git的介紹文章數不勝數,但是依然有很多人(包括我自己在內)對於它的功能不能完全掌握。以下的介紹只是基於我個人對於git的理解,並且可能生編硬造了一些不完全符合git說法的詞語。

目的只是為了讓git通俗化,使初學者也能大概了解如何快速上手git。同時,下面所有討論,我們都假設只使用乙個分支,也就是主分支master的情況,雖然這種作法並不符合git規範,但是現實情況中絕大部分使用者是直接在master分支上進行工作的,所以在這裡我們不去引入更加複雜的各種分支的情況,也不涉及標籤tag的操作,只講在最簡單的主分支上如何回退。

正常情況下,我們的工作流就是3個步驟,對應上圖中的3個箭頭線:

1

git add .

2 git commit -m "

comment

"3 git push

git add .把所有檔案放入暫存區;

git commit把所有檔案從暫存區提交進本地倉庫;

git push把所有檔案從本地倉庫推送進遠端倉庫。

git之所以令人費解,主要是它相比於svn等等傳統的版本管理工具,多引入了乙個暫存區(stage)的概念,就因為多了這乙個概念,而使很多人疑惑。其實,在初學者來說,每個區具體怎麼工作的,我們完全不需要關心,而只要知道有這麼4個區就夠了:

以上4個區,進入每乙個區成功之後會產生乙個狀態,再加上最初始的乙個狀態,一共是5種狀態。以下我們把這5種狀態分別命名為:

了解了基本概念之後,我們來談一談犯錯誤之後如何撤銷的問題。首先,我們要了解如何檢查這3個步驟當中每乙個步驟修改了什麼,然後才好判斷有沒有修改成功。檢查修改的二級命令都相同,都是diff,只是引數有所不同。

git diff

首先,我們來看一下,如果我們只是簡單地在瀏覽器裡儲存了一下檔案,但是還沒有做git add .之前,我們如何檢查有哪些修改。我們先隨便拿乙個檔案來做一下實驗:

我們在檔案開頭的第2行胡亂加了4個數字1234,存檔,這時檔案進入了已修改狀態,但是還沒有進入暫存區,我們執行git diff,結果如下:

git a/index.md b/index.md

index 73ff1ba..1066758 100644

--- a/index.md

+++ b/index.md

@@ -1,5 +1,5@@

----layout: main

+1234layout: main

color: black

---

git diff的結果告訴我們哪些檔案已經做了哪些修改。

已暫存,未提交

git diff --cached

現在我們把修改放入暫存區看一下。先執行git add .,然後執行git diff,你會發現沒有任何結果:

這說明git diff這個命令只檢查我們的工作區和暫存區之間的差異,如果我們想看到暫存區和本地倉庫之間的差異,就需要加乙個引數git diff --cached

diff --git a/index.md b/index.md

index 73ff1ba..1066758 100644

--- a/index.md

+++ b/index.md

@@ -1,5 +1,5@@

----layout: main

+1234layout: main

color: black

---

這時候我們看到的差異是暫存區和本地倉庫之間的差異。

已提交,未推送

git diff master origin/master

現在,我們把修改從暫存區提交到本地倉庫,再看一下差異。先執行git commit,然後再執行git diff --cached,沒有差異,執行git diff master origin/master,可以看到差異:

在這裡,master就是你的本地倉庫,而origin/master就是你的遠端倉庫,master是主分支的意思,因為我們都在主分支上工作,所以這裡兩邊都是master,而origin就代表遠端。

了解清楚如何檢查各種修改之後,我們開始嘗試各種撤銷操作。

git checkout .

或者git reset --hard

來進行撤銷操作。

可以看到,在執行完git checkout .之後,修改已被撤銷,git diff沒有任何內容了。

一對反義詞 git add .的反義詞是git checkout .。做完修改之後,如果你想向前走一步,讓修改進入暫存區,就執行git add .,如果你想向後退一步,撤銷剛才的修改,就執行git checkout .。

你已經執行了git add .,但還沒有執行git commit -m "comment"。這時候你意識到了錯誤,想要撤銷,你可以執行:

git resetgit checkout . 或者

git reset --hard

git reset只是把修改退回到了git add .之前的狀態,也就是說檔案本身還處於已修改未暫存狀態,你如果想退回未修改狀態,還需要執行git checkout .。

或許你已經注意到了,以上兩個步驟都可以用同乙個命令git reset --hard來完成。是的,就是這個強大的命令,可以一步到位地把你的修改完全恢復到未修改的狀態。

已提交,未推送

你的手太快,你既執行了git add .,又執行了git commit,這時候你的**已經進入了你的本地倉庫,然而你後悔了,怎麼辦?不要著急,還有辦法。

git reset --hard origin/master

還是這個git reset --hard命令,只不過這次多了乙個引數origin/master,正如我們上面講過的,origin/master代表遠端倉庫,既然你已經汙染了你的本地倉庫,那麼就從遠端倉庫把**取回來吧。

已推送

很不幸,你的手實在是太快了,你既git add了,又git commit了,並且還git push了,這時你的**已經進入遠端倉庫。如果你想恢復的話,還好,由於你的本地倉庫和遠端倉庫是等價的,你只需要先恢復本地倉庫,再強制push到遠端倉庫就好了:

git reset --hard head^

git push -f

以上4種狀態的撤銷我們都用到了同乙個命令git reset --hard,前2種狀態的用法甚至完全一樣,所以只要掌握了git reset --hard這個命令的用法,從此你再也不用擔心提交錯誤了。

Git 的4個階段的撤銷更改

雖然git誕生距今已有12年之久,網上各種關於git的介紹文章數不勝數,但是依然有很多人 包括我自己在內 對於它的功能不能完全掌握。以下的介紹只是基於我個人對於git的理解,並且可能生編硬造了一些不完全符合git說法的詞語。目的只是為了讓git通俗化,使初學者也能大概了解如何快速上手git。同時,下...

git 撤銷更改的檔案

在沒有git add之前 1.撤銷所有更改 git checkout 2.撤銷指定檔案的更改 git checkout file.txt git add之後 git reset head file.txt git push 之後 git reset hard comitthash git log o...

不容錯過的git各階段撤銷總結

git checkout 檔名稱 git reset head 檔名稱 git checkout 檔名稱 git log檢視提交的日誌,然後找到想要回到的地方 例如 只是不想要剛剛的這個提交,那麼找到剛剛的這個提交的上乙個提交,然後複製他的commitid,複製前幾位就行 git reset har...