天天看點

Git復原和撤銷---吃上後悔藥、坐上時光機

本文首發于公衆号“AntDream”,歡迎微信搜尋“AntDream”或掃描文章底部二維碼關注,和我一起每天進步一點點

送出分3步:add、commit、push,復原和撤銷也分3種情況:

  • 撤銷add
  • 撤銷commit
  • 復原push,也就是復原遠端倉庫的代碼

這種情況有可能是在

git add

操作的時候一些不必要的檔案也加進來了,是以想撤銷,重新

add

add

操作前面我們已經學習了,它的本質就是将工作目錄中的檔案的内容儲存到了Git資料庫,并把檔案名和對應的資料對象這些資訊添加到了暫存區中。

由于添加的檔案内容已經添加到Git資料庫中了,沒法删除,是以我們不用管Git資料庫中的。我們可以删除暫存區中的檔案,以確定不會出現在送出記錄中。(那我要是這個檔案就是一直不需要送出的,那Git資料庫中一直存在着?)

//删除暫存區中的檔案記錄
git rm --cached 檔案名
//或是下面的指令,推薦用下面這種
git reset HEAD 檔案名           

上面2種方法有什麼差別呢?

git rm —cached

是直接删除暫存區中的檔案記錄,用

git ls-files —stage

指令檢視暫存區會發現對應檔案的記錄被删除了,工作區的内容不會變;

git reset

是把内容恢複到指定的commit送出版本,上述指令中的HEAD就是表示最近一次送出。當檔案之前沒有送出過時,效果就會等同于上面的指令;如果之前送出記錄裡有檔案的其他版本,就會把暫存區的記錄更新到之前的版本,這樣以來對應檔案内容就是之前的版本。

同樣的,執行了commit 指令以後,就已經建立了 commit對象,并且存入了Git倉庫中,存入了就不能被删除了。

那撤銷commit 本質是什麼?

之前我們已經學習過,commit的過程就是根據暫存區的内容,建立一個 commit 對象存入Git倉庫,同時這個commit 對象儲存了上一個 commit 對象的資訊,這樣就有了送出曆史記錄,與此同時更新目前分支指向新的commit。

撤銷commit 本質上就是将分支指向上一個commit。

隻不過有個問題,暫存區中的内容和工作區中的内容要不要跟着改呢?Git可以讓我們自己選——分别對應

reset

的3個參數:mixed、soft和hard

  • mixed: 這個是預設值,效果是暫存區的内容會被替換,工作區的内容不變(也就是撤銷commit,同時撤銷add,需要重新add操作);
  • soft:效果是暫存區和工作區的内容都不會變,也就是不撤銷 add 操作;
  • hard:這個效果是暫存區的内容會被替換,工作區之前被跟蹤的檔案内容會被替換
//復原到上一次送出
git reset --hard HEAD^
//或者
git reset HEAD^ --hard           

PS:如果隻是想修改剛剛commit時寫的送出備注,不用

reset

,可以用下面的指令:

//修改最新一次送出的說明資訊
git commit --amend -m 新的說明資訊           

復原push

首先,這是復原公共倉庫中的代碼操作,慎重!

復原遠端倉庫實際上就是要将遠端倉庫中的目前分支引用指向其他的commit。

那思路就來了,如果我可以直接操作遠端倉庫的話,那我直接就在目前分支執行一下

reset

操作就完了。

當然了,咱不能直接操作遠端倉庫。哈哈...

那我們可不可以更新遠端倉庫的分支指向的送出呢?這個當然可以,我們每次

push

操作就是在更新遠端倉庫對應的分支呀!

那另一個思路就來了,我本地復原一下,然後

push

上去不就行了嘛!

//本地改完以後需要強制推送到遠端
git push origin HEAD --force
//這個指令會把目前本地分支的引用強制更新到遠端           

需要注意的是,要加一個

--force

參數,表示強制更新。

歡迎關注我的公衆号檢視更多精彩文章!