場景
線上分支:master
你開發的分支:dev1
同時開發的分支:dev2
dev1分支開發的代碼已經上線,並且已經merge到master
同時dev2分支也已上線,並且已經merge到master
這時發現dev1的巨大bug,線上版本要把這個分支的代碼全部移除。
想要達到的效果
我們要撤銷所有dev1的合併,並且保留dev2的代碼。
同時本地dev1的分支不想刪除這些代碼,還有在這基礎上開發。
master分支
如果使用reset,那麼線上的幾個提交記錄都不會保留,達不到我們想要的效果。
這裏使用git revert。
首先我們要撤銷所有dev1的更改,找到dev1的兩次commit id
git revert 63db9b1228c9e38a015513f834a42fa55002fca8
git revert a407174c5df3e47e1866663e4c3fe611419eb5a8
此時master已經達到我們想要的效果:
開發分支
這時回到我們的dev1分支,修復bug,我還要保留以前提交的代碼。
但是在上線前總要先merge master,但是master的兩次revert是領先你的,一旦merge後你的代碼就沒有了。
下面是當前dev1的提交情況
所以我們要在merge master後,再使用revert撤銷這次merge。
但是這時你發現,在merge完master之後你又在這個分支提交了新代碼,這時revert就會報錯:
git revert ce479b597de6025da4a67ddd4a94d1b8034d8c67
error: commit ce479b597de6025da4a67ddd4a94d1b8034d8c67 is a merge but no -m option was given.
fatal: revert failed
這是因爲撤銷的是一次合併,git不知道要保存這兩個分支中哪個的修改。
-m 1 表示保留當前分支的更改
-m 2 表示保留master更改
我們目的是爲了保留dev1的代碼,所以要保留當前代碼,即使用 -m 1
git revert -m 1
ce479b597de6025da4a67ddd4a94d1b8034d8c67
[dev1 bb363fa] Revert "Merge branch 'master' into dev1"
2 files changed, 0 insertions(+), 0 deletions(-)
rename dev2 add => b (100%)
create mode 100644 c
執行完上面的代碼,我們就會發現,代碼又回來了,和master沒有回滾前的代碼一樣。
修完bug,再把當前代碼合併到master,然後你就會發現,dev2提交的代碼被你的merge幹掉了???
這是因爲你的那次rever合併採用了你的分支代碼,但是你的dev1分支並沒有dev2的代碼...
所以我們應該在master回滾前,回到dev1分支,先merge一次最新代碼,再執行後面的操作。
總結
總結起來流程很簡單。
1.保持你要開發的分支同步了master最新代碼。
2.revert所有該分支的提交。
3.回到你的分支merge master。
4.revert merge master的那次提交。