1. 程式人生 > 其它 >git撤銷已經執行操作的檔案

git撤銷已經執行操作的檔案

已經add的檔案

眾所周知,Git把檔案劃分為三個區,分別是工作區、暫存區和本地倉庫,那麼add後的檔案已經提交到暫存區了,這時候我們想要把add後的檔案的還原到未新增以前的操作,那麼我們該怎麼辦呢?

  1. 如果還想保留修改內容的話,可以直接使用下面的命令把檔案從暫存區刪除掉:git rm --cache -r 1.txt,這時候還有點不一樣的地方,
    • 如果是新建立的檔案,使用這個命令,可以直接從暫存區刪除掉,轉到工作區。
    • 如果是修改的檔案,使用這個命令,那麼檔案會變成刪除的狀態,意思就是從本地倉庫刪除的意思,再執行一次commit,就會把檔案從倉庫刪除掉,檔案進入暫存區,檔案修改的內容不會改變。
  2. 如果不需要保留修改內容的話,可以直接使用版本還原命令:git reset --hard <版本號>,例如git reset --hard c5775(版本號一般寫5位即可,要保證填寫的這幾位不出現重複即可),特別特別注意,正如它的名字一樣,這是很硬核的命令,這裡會把整個工作區撤銷到某個版本,會把這個版本以後你新增或者修改的內容全部刪除掉,回收站和本地倉庫都找不來的那種。 比較有意思的一點是未新增到版本控制的檔案(即那些未執行add操作的檔案不會被刪除)。

已經commit的檔案

這時候的檔案已經進入本地倉庫了,這時候的撤銷就會出現不同的情況了,是要撤銷到暫存區還是工作區呢?這時候多了不同的選擇,具體的操作接著往下看。

  1. 撤銷檔案到暫存區,這時只是撤銷commit的操作,對應的命令是:git reset --soft <版本號>(例如git reset --soft c5775),此時你會發現對應的檔案被撤銷了,但是修改內容還是存在的,並且檔案在暫存區,此時如果你想再撤銷add操作的話,可以參考第一種情況。
  2. 撤銷檔案到工作區,如果需要刪除工作區改動的內容的話,可以使用命令:git reset --hard <版本號>(例如git reset --hard c5775),正如第一種情況中提到的,在撤銷commit操作的同時會撤銷add操作,並且把你修改和新增的內容全部刪除掉,可以試著先撤銷到最近提交的版本,這樣可以把檔案的變動降低到最小。
  3. 撤銷檔案到工作區,並保留修改的內容,然後撤銷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。這個是連續性,會把commit1commit2之間所有的修改都撤銷了,包括commit2t提交記錄的修改。而且revert對每個撤銷的commit記錄都會生成一個新的提交,產生一次提交記錄。--no-commit 表示可以最後一起手動提交,避免產生太多提交記錄。

那麼問題又來了,如果你對某檔案進行了多次修改,多次修改的是同一塊程式碼,然後再撤銷很久很久以前一次提交,那麼會出現什麼後果呢?

這時候再使用revert的話,會出錯的,提醒無法復原檔案,但是git會把執行結果展示在檔案中,git會把檔案劃分為兩部分,一部分包括檔案現在的內容,一部分包括檔案復原版本的上一個版本的內容。中間以=======劃分。最終的內容由使用者自己決定。

<<<<<<< HEAD
檔案現在的內容
=======
檔案在復原後,上一個版本的內容
>>>>>>> parent of e686989... modify 2.txt

修改完成以後,執行add和commit即可。


git resetgit revert的區別可以用一句話概括下來:git reset --hard 撤銷某次提交,git revert撤銷某次提交 。