Git 實用操做:撤銷 Commit 提交(動圖講解)

有的時候,改完代碼提交 commit 後發現寫得實在太爛了,連本身的都看不下去,與其修改它還不如丟棄重寫。怎麼操做呢?git

使用 reset 撤銷

若是是最近提交的 commit 要丟棄重寫能夠用 reset 來操做。好比你剛寫了一個 commit:shell

寫完回頭看了看,你以爲不行這得從新寫。那麼你能夠用 reset --hard 來撤銷這條 commit。bash

git reset --hard HEAD^

HEAD^ 表示往回數一個位置的 commit`,上篇剛說過。this

由於你要撤銷最新的一個 commit,因此你須要恢復到它的父 commit ,也就是 HEAD^。那麼在這行以後,你要丟棄的最新一條就被撤銷了:3d

不過,就像圖上顯示的,你被撤銷的那條提交併無消失,只是你再也不用到它了。若是你在撤銷它以前記下了它的 SHA-1 碼,那麼你還能夠經過 SHA-1 來找到他它。rest

使用 rebase -i 撤銷

假若有一個 commit,你在剛把它寫完的時候並無以爲它很差,但是在以後又寫了幾個提交之後,你忽然靈光一現:哎呀,那個 commit 不應寫,我要撤銷!code

不是最新的提交,就不能用 reset --hard 來撤銷了。這種狀況的撤銷,就要用以前介紹過的一個指令交互式變基:rebase -iblog

以前介紹過,交互式變基能夠用來修改某些舊的 commit。其實除了修改提交,它還能夠用於撤銷提交。好比下面這種狀況:rem

你想撤銷倒數第二條 commit,那麼可使用 rebase -iit

git rebase -i HEAD^^

Git 引導到選擇要操做的 commit 頁面:

pick 310154e 第 N-2 次提交
pick a5f4a0d 第 N-1 次提交

# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
...

在上篇中,講到要修改哪一個 commit 就把哪一個 commit 前面的 pick 改爲 edit。而若是你要撤銷某個 commit ,作法就更加簡單粗暴一點:直接刪掉這一行就好(使用 d 命令)。

pick a5f4a0d 第 N-1 次提交

# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
...

把這一行刪掉就至關於在 rebase 的過程當中跳過了這個 commit,從而也就把這個 commit 丟棄了。

若是你經過 git log 查看,就會發現以前的倒數第二條 commit 已經不在了。

使用用 rebase --onto 撤銷

除了用交互式 rebase,你還能夠用 rebase --onto 來更簡便地撤銷提交。

rebase 加上 --onto 選項以後,能夠指定 rebase 的「起點」。通常的 rebase, 的「起點」是自動選取的,選取的是當前 commit 和目標 commit 在歷史上的交叉點。

例以下面這種狀況:

若是在這裏執行:

git rebase 第3個commit

那麼 Git 會自動選取 35 的歷史交叉點 2 做爲 rebase 的起點,依次將 45 從新提交到 3 的路徑上去。

--onto 參數,就能夠額外給 rebase 指定它的起點。例如一樣以上圖爲例,若是我只想把 5 提交到 3 上,不想附帶上 4,那麼我能夠執行:

git rebase --onto 第3個commit 第4個commit branch1

選項 --onto 參數後面有三個附加參數:目標 commit、起點 commit(注意:rebase 的時候會把起點排除在外)、終點 commit。因此上面這行指令就會從 4 往下數,拿到 branch1 所指向的 5,而後把 5 從新提交到 3 上去。

一樣的,你也能夠用 rebase --onto 來撤銷提交:

git rebase --onto HEAD^^ HEAD^ branch1

上面這行代碼的意思是:以倒數第二個 commit 爲起點(起點不包含在 rebase 序列裏),branch1 爲終點,rebase 到倒數第三個 commit 上。

也就是這樣:

總結

撤銷最近一次的 commit 直接使用 reset --hard,撤銷過往歷史提交。方法有兩種:

  1. git rebase -i 在編輯界面中刪除想撤銷的 commit
  2. git rebase --onto 在 rebase 命令中直接剔除想撤銷的 commit

這有兩種理念是同樣的,即在 rebase 的過程當中去掉想撤銷的 commit,讓它消失在歷史中。

相關文章
相關標籤/搜索