revert 用來取消置頂的提交的內容git
當討論 revert 時,須要分兩種狀況,由於 commit 分爲兩種:spa
git commit
提交的 commit; 須要明確:在使用 git merge
合併兩個分支以後,你將會獲得一個新的 merge commit。merge commit 和普通 commit 的不一樣之處在於 merge commit 包含兩個 parent commit,表明該 merge commit 是從哪兩個 commit 合併過來的。code
在上圖所示的紅框中有一個 merge commit,使用 git show
命令能夠查看 commit 的詳細信息blog
➜ git show bd86846 commit bd868465569400a6b9408050643e5949e8f2b8f5 Merge: ba25a9d 1c7036f
這表明該 merge commit 是從 ba25a9d 和 1c7036f 兩個 commit 合併過來的。開發
而常規的 commit 則沒有 Merge 行it
➜ git show 3e853bd commit 3e853bdcb2d8ce45be87d4f902c0ff6ad00f240a
使用 git revert <commit id>
便可,git 會生成一個新的 commit,將指定的 commit 內容從當前分支上撤除。ast
revert merge commit 有一些不一樣,這時須要添加 -m
選項以表明此次 revert 的是一個 merge commitclass
但若是直接使用 git revert <commit id>
,git 也不知道到底要撤除哪一條分支上的內容,這時須要指定一個 parent number 標識出"主線",主線的內容將會保留,而另外一條分支的內容將被 revert。bug
如上面的例子中,從 git show 命令的結果中能夠看到,merge commit 的 parent 分別爲 ba25a9d 和 1c7036f,其中 ba25a9d 表明 master 分支(從圖中能夠看出),1c7036f 表明 will-be-revert 分支。須要注意的是 -m 選項接收的參數是一個數字,數字取值爲 1 和 2,也就是 Merge 行裏面列出來的第一個仍是第二個。im
咱們要 revert will-be-revert 分支上的內容,即 保留主分支,應該設置主分支爲主線,操做以下:
➜ git revert -m 1 bd86846
假設你本身分支 goudan/a-cool-feature 上開發了一個功能,併合併到了 master 上,以後 master 上又提交了一個修改 h,這時提交歷史以下:
忽然,你們發現你的分支存在嚴重的 bug,須要 revert 掉,因而你們把 g 這個 merge commit revert 掉了,記爲 G,以下:
而後你回到本身的分支進行 bug_fix,修好以後想從新合併到 master,直覺上只須要再 merge 到 master 便可
i 是新的 merge commit。但須要注意的是,這 不能 獲得咱們指望的結果。由於 d 和 e 兩個提交曾經被丟棄過,如此合併到 master 的代碼,並不會從新包含 d 和 e 兩個提交的內容,至關於只有 goudan/a-cool-feature 上的新 commit 被合併了進來,而 goudan/a-cool-feature 分支以前的內容,依然是被 revert 掉了。
因此,若是想恢復整個 goudan/a-cool-feature 所作的修改,應該先把 G revert 掉:
其中 G' 是對 G 的 revert 操做生成的 commit,把以前撤銷合併時丟棄的代碼恢復了回來,而後再 merge 狗蛋的分支,把解決 bug 寫的新代碼合併到 master 分支。
能夠通俗的來理解:相對你本身 G 是經過別人來遠程操做的 revert 操做,相對於別人來講此時的 master 分支已經不存在 d 和 e 兩個提交的內容,而你本身本地分支上並無進行 revert 操做,相對於其餘人來講你本地認爲 master 分支還保存有 d 和 e 提交的內容,若是直接合並的話會報錯,故須要你本身在本地直接 revert 操做,將 g 點聯繫釋放掉,和線上原始 master 分支保持乾淨完整的鏈路,這樣就能夠正常的 merge commit 了。