1. 程式人生 > >git 撤銷操作--git checkout、git reset、git revert、git commit -- amend

git 撤銷操作--git checkout、git reset、git revert、git commit -- amend

git 撤銷操作

一、前言

在使用git過程當中經常會用到撤銷一些已經完成的操作,經常會用到git checkoutgit resetgit revertgit commit -- amend。在用法上也有不同之處,簡單的分析下這幾種方法的不同。

首先簡單看一下git的一個簡單流程(簡單的流程,可以結合下面的圖看一下):

  • 在工作區進行修改、操作,檔案一般處於modifiedUntracked
  • git add 就是把檔案修改新增到暫存區
  • git commit 就是把暫存區的所有內容提交到當前分支。



二、git commit – amend

這個命令主要是修改最近一次的提交的modify message

。比如我們在通過git commit -m'modify message'提交修改資訊。之後發現修改資訊有誤可以通過git commit --amend修改已經提交的資訊:


圖片名稱

使用vim編輯需要的資訊:


圖片名稱

圖片名稱

w+q儲存退出


圖片名稱

這樣就OK了。

第一次使用git commit -- amend 預設的編輯器可能不是vim可能會遇到一個bug:There was a problem with the editor ‘vi’ bug修復傳送門~點選

三、git checkout

git checkout

一些常用的用法:

git checkout [-q] [< commit >] [–] \< paths >…

git checkout [< branch >]

git checkout [-m] [[-b]–orphan] < new_branch >] [< commit__id >]

今天主要討論一下git checkout撤銷的一些操作

  1. git checkout || git checkout HEAD || git checkout [< commit__id >]
  2. git checkout -- filename
  3. git checkout branch -- filename
  4. git checkout -- . || git checkout .
引數 作用
git checkout || git checkout HEAD 顯示工作區、暫存區與HEAD的差異
git checnkout -[< commit__id >] 切換至指定節點的程式碼庫(git節點都含有一個完整的程式碼倉庫),如 git checnkout -[3e07fd8]
git checkout -- filename 用暫存區中filename檔案來覆蓋工作區中的filename檔案。相當於取消自上次執行git add/commit以來(如果執行過)的本地修改
git checkout branch -- filename HEAD不變。用branch所指向的提交中filename替換暫存區和工作區中相應的檔案。注意會將暫存區和工作區中的filename檔案直接覆蓋。
git checkout -- . || git checkout . 相當於用暫存區的所有檔案直接覆蓋本地檔案,危險操作⚠️

四、git reset

簡單說一下git reflog:

git reflog

顯示整個本地倉儲的commit, 包括所有branchcommit, 甚至包括已經撤銷的commit, 只要HEAD發生了變化, 就會在reflog裡面看得到. git log只包括當前分支的commit.

git reflog查詢結果為下:


圖片名稱
引數 作用
git reset HEAD 任何事情都不會發生,這是因為我們告訴GIT重置這個分支到HEAD,而這個正是它現在所在的位置(上圖的3e07fd8位置)。
git reset HEAD~1 則意味著將HEAD從頂端的commit往下移動一個更早的commit
git reset HEAD~2 則意味著將HEAD從頂端的commit往下移動兩個更早的commit

在看一下各個引數:

引數 作用
soft –soft引數使git重置HEAD到另外一個commit。意味著工作區、暫存區都不會做任何變化,所有的在 HEAD和重置到的那個commit之間的所有變更集仍然在暫存區(index)區域中。
hard –hard引數將會blow out everything。它將重置HEAD到另外一個commit,重置快取區以便反映HEAD的變化,並且重置工作區也使得其完全匹配起來。這是一個比較危險的操作⚠️,具有破壞性!
mixed(default) –mixed是reset的預設引數。它將重置HEAD到另外一個commit,並且重置快取區。工作區不會被更改。所以所有從HEAD到你重置到的那個commit之間的所有變更仍然儲存在工作區中,被標示為已變更

舉個簡單的例子: git reset --mixed [版本號]


圖片名稱

1.先git commit提交一部分內容,在通過git reset --mixed 62aba96,撤銷最後一次的提交。

圖片名稱

2.在通過git diff檢視修改過的內容。會發現[62aba96]提交的內容,回到了工作區

圖片名稱

3.這個時候通過git reflog檢視最上面兩條資訊,一條是git commit的資訊,一條是git reset的資訊。

五、git revert

如果簡單的說一下git revert的作用,通過建立一條新的commit,覆蓋之前的某一次commit所提交的內容,但是不會影響之前的提交資訊。

Given one or more existing commits, revert the changes that the related patches introduce, and record some new commits that record them. This requires your working tree to be clean (no modifications from the HEAD commit).

引數 作用
git revert HEAD 撤銷上一次的commit
git revert HEAD^ 撤銷上上一次的commit
git revert [commit-id] 撤銷到指定的某一次的commit

舉個簡單的例子:


圖片名稱
  1. commit提交一條內容。
  2. 在通過git revert HEAD
  3. 在通過git reflog(下圖)和git log -p(下圖)檢視會發現,有條commmit覆蓋了之前commit的操作。

圖片名稱

圖片名稱

六、參考