git撤銷已經執行操作的檔案
已經add的檔案
眾所周知,Git把檔案劃分為三個區,分別是工作區、暫存區和本地倉庫,那麼add後的檔案已經提交到暫存區了,這時候我們想要把add後的檔案的還原到未新增以前的操作,那麼我們該怎麼辦呢?
- 如果還想保留修改內容的話,可以直接使用下面的命令把檔案從暫存區刪除掉:
git rm --cache -r 1.txt
,這時候還有點不一樣的地方,- 如果是新建立的檔案,使用這個命令,可以直接從暫存區刪除掉,轉到工作區。
- 如果是修改的檔案,使用這個命令,那麼檔案會變成刪除的狀態,意思就是從本地倉庫刪除的意思,再執行一次commit,就會把檔案從倉庫刪除掉,檔案進入暫存區,檔案修改的內容不會改變。
- 如果不需要保留修改內容的話,可以直接使用版本還原命令:
git reset --hard <版本號>
,例如git reset --hard c5775
(版本號一般寫5位即可,要保證填寫的這幾位不出現重複即可),特別特別注意,正如它的名字一樣,這是很硬核的命令,這裡會把整個工作區撤銷到某個版本,會把這個版本以後你新增或者修改的內容全部刪除掉,回收站和本地倉庫都找不來的那種。 比較有意思的一點是未新增到版本控制的檔案(即那些未執行add操作的檔案不會被刪除)。
已經commit的檔案
這時候的檔案已經進入本地倉庫了,這時候的撤銷就會出現不同的情況了,是要撤銷到暫存區還是工作區呢?這時候多了不同的選擇,具體的操作接著往下看。
- 撤銷檔案到暫存區,這時只是撤銷commit的操作,對應的命令是:
git reset --soft <版本號>
(例如git reset --soft c5775
),此時你會發現對應的檔案被撤銷了,但是修改內容還是存在的,並且檔案在暫存區,此時如果你想再撤銷add操作的話,可以參考第一種情況。 - 撤銷檔案到工作區,如果需要刪除工作區改動的內容的話,可以使用命令:
git reset --hard <版本號>
(例如git reset --hard c5775
),正如第一種情況中提到的,在撤銷commit操作的同時會撤銷add操作,並且把你修改和新增的內容全部刪除掉,可以試著先撤銷到最近提交的版本,這樣可以把檔案的變動降低到最小。 - 撤銷檔案到工作區,並保留修改的內容,然後撤銷commit,撤銷add操作,這時候就要使用另外一個命令引數了:
git reset --mixed <版本號>
(例如git reset --mixed c5775
),此時該版本後面的的commit和add都會被撤回的,但是修改以後的內容並沒有被刪除掉。- 所有新建立的檔案都會回到工作區
- 所有提交後修改的檔案會到暫存區
- 所有在這個版本以後提交併修改的檔案,會回到工作區,並且修改內容不變。
- 預設情況下,
git reset
後面不跟引數時,使用的是--mixed
拓展知識:只修改提交的說明內容
如果只是提交時的說明內容寫錯了,那麼可以使用另外一條命令進行修改:git commit --amend
,這條命令不需要跟版本號,只會修改最近一次commit的說明內容,執行以後會進入vim編輯器,後面的操作同vim的基礎操作。
已經push的檔案
執行push的檔案已經進入遠端倉庫,突然發現檔案提交錯了,這是不是感覺比較慌?不用緊張,當你掌握了前面的那些操作以後,你會發現此時的操作也沒那麼難嘛。
改變遠端倉庫的檔案只要兩步,首先撤銷本地倉庫的修改,然後推送到遠端倉庫即可。但是,這時候會遇到一個問題。
因為執行撤銷操作以後,導致本地的版本號低於遠端倉庫的版本號,這時候執行推送的操作就會變錯。就需要我們執行強制推送,命令如下所示:
git push origin <分支名> –force (例如:git push origin master –force )
- 或者使用:
git push -f origin master
git reset 和 git revert
revert可以理解為復原,相當於對某些操作的逆轉。關於git revert
有以下幾個注意點:
- 基本的使用操作是
git revert <版本號>
,撤銷某次提交 git revert
操作會產生一次新的commit
我們可不可以只產生一次新的commit完成批量撤銷復原操作呢?
嘿嘿,這也是可以的。撤銷一串提交可以使用的命令是:git revert --no-commit <commit1>..<commit2>
,這是一個前開後閉的區間選擇,意思就是不包括commit1,但包括commit2。這個是連續性,會把commit1
和commit2
之間所有的修改都撤銷了,包括commit2t
提交記錄的修改。而且revert對每個撤銷的commit記錄都會生成一個新的提交,產生一次提交記錄。--no-commit
表示可以最後一起手動提交,避免產生太多提交記錄。
那麼問題又來了,如果你對某檔案進行了多次修改,多次修改的是同一塊程式碼,然後再撤銷很久很久以前一次提交,那麼會出現什麼後果呢?
這時候再使用revert的話,會出錯的,提醒無法復原檔案,但是git會把執行結果展示在檔案中,git會把檔案劃分為兩部分,一部分包括檔案現在的內容,一部分包括檔案復原版本的上一個版本的內容。中間以=======
劃分。最終的內容由使用者自己決定。
<<<<<<< HEAD
檔案現在的內容
=======
檔案在復原後,上一個版本的內容
>>>>>>> parent of e686989... modify 2.txt
修改完成以後,執行add和commit即可。
git reset
和git revert
的區別可以用一句話概括下來:git reset --hard
撤銷到某次提交,git revert
撤銷某次提交 。