Git 实用操作 | 撤销 Commit 提交
有的時候,改完代碼提交 commit 后發(fā)現寫得實在太爛了,連自己的都看不下去,與其修改它還不如丟棄重寫。怎么操作呢?
使用 reset 撤銷
如果是最近提交的 commit 要丟棄重寫可以用 reset 來操作。比如你剛寫了一個 commit:
寫完回頭看了看,你覺得不行這得重新寫。那么你可以用 reset --hard 來撤銷這條 commit。
git?reset?--hard?HEAD^HEAD^ 表示往回數一個位置的 commit`,上篇剛說過。
因為你要撤銷最新的一個 commit,所以你需要恢復到它的父 commit ,也就是 HEAD^。那么在這行之后,你要丟棄的最新一條就被撤銷了:
不過,就像圖上顯示的,你被撤銷的那條提交并沒有消失,只是你不再用到它了。如果你在撤銷它之前記下了它的 SHA-1 碼,那么你還可以通過 SHA-1 來找到他它。
使用 rebase -i 撤銷
假如有一個 commit,你在剛把它寫完的時候并沒有覺得它不好,可是在之后又寫了幾個提交以后,你突然靈光一現:哎呀,那個 commit 不該寫,我要撤銷!
不是最新的提交,就不能用 reset --hard 來撤銷了。這種情況的撤銷,就要用之前介紹過的一個指令交互式變基:rebase -i。
之前介紹過,交互式變基可以用來修改某些舊的 commit。其實除了修改提交,它還可以用于撤銷提交。比如下面這種情況:
你想撤銷倒數第二條 commit,那么可以使用 rebase -i:
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 查看,就會發(fā)現之前的倒數第二條 commit 已經不在了。
使用用 rebase --onto 撤銷
除了用交互式 rebase,你還可以用 rebase --onto 來更簡便地撤銷提交。
rebase 加上 --onto 選項之后,可以指定 rebase 的「起點」。一般的 rebase, 的「起點」是自動選取的,選取的是當前 commit 和目標 commit 在歷史上的交叉點。
例如下面這種情況:
如果在這里執(zhí)行:
git?rebase?第3個commit那么 Git 會自動選取 3 和 5 的歷史交叉點 2 作為 rebase 的起點,依次將 4 和 5 重新提交到 3 的路徑上去。
而 --onto 參數,就可以額外給 rebase 指定它的起點。例如同樣以上圖為例,如果我只想把 5 提交到 3 上,不想附帶上 4,那么我可以執(zhí)行:
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,撤銷過往歷史提交。方法有兩種:
用 git rebase -i 在編輯界面中刪除想撤銷的 commit
用 git rebase --onto 在 rebase 命令中直接剔除想撤銷的 commit
這有兩種理念是一樣的,即在 rebase 的過程中去掉想撤銷的 commit,讓它消失在歷史中。
-
精致碼農
帶你洞悉編程與架構
↑長按圖片識別二維碼關注,不要錯過網海相遇的緣分
總結
以上是生活随笔為你收集整理的Git 实用操作 | 撤销 Commit 提交的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TIOBE 9 月榜单:C#上涨1.18
- 下一篇: Istio Pilot 源码分析(一)