![](/img/trans.png)
[英]git: I accidentally merged feature branch into master instead of develop
[英]Accidentally merged master into develop and pushed
我在一個git倉庫工作,我們維護一個主人和一個開發分支。 在開發之前進行更改並在發布之前合並到master中。 今天我不小心把大師合並到了開發中並推動了結果的發展。 現在開發的git log
顯示merge develop into master
提交。 我需要以某種方式解決這個問題。 我使用git reflog
找到了最近的好提交。 恢復它的正確方法是什么?
由於我已經推,我想避免重寫歷史。 但是,我不確定我是否可以使用git revert
。 我不相信“恢復錯誤的合並”howto和其他SO問題適用,因為我想要恢復的提交是自己合並的( https://www.kernel.org/pub/software/scm/git/docs /howto/revert-a-faulty-merge.txt )。
您可以使用git revert
還原合並。 請注意,當您這樣做時,您將使未來“重新合並”變得更加困難。 閱讀你密切關注的那條消息 - 它說了很多關於如何使未來“重新合並”的工作 - 但要注意它正在談論將develop
合並到master
,你說你做了相反的,合並的master
進入develop
:
A -- B -- C -- D -- E <-- master
\ \
F - G - H - M <-- develop
在這種情況下(將master
合並為develop
而不是相反)你可以選擇許多不同的選項,所有選項都有優點和缺點......
(0)什么都不做。 如果在C
和D
中合並不會破壞develop
分支,那么就這樣離開。 后來,有人會git checkout master
和git merge --no-ff develop
並得到這個(假設I
再加入一個提交以進行develop
):
A -- B -- C -- D -- E -- M2 <-- master
\ \ /
F - G - H - M - I <-- develop
這里merge
找到了develop
已經完成的工作,因為它從master
處分離出來,這是在B
。 所以它把在F
, G
,而H
,跳過的任何部分M
是來到了master
(可能是所有的話),最后提出在I
,使合並提交M2
(因為提交的E
;但如果E
不存在,那是因為我使用了--no-ff
)。
(1)只是“重寫歷史”:從分支develop
擦除提交M
警告使用該分支即將發生的所有其他人:提交M
即將離開,他們應該采取他們必須采取的任何措施來處理這個問題。
(2)停止使用舊名稱develop
,創建一個新的分支名稱develop1
或者其他:
A -- B -- C -- D -- E <-- master
| \
| M <-- develop
\ /
F - G - H <-- develop1
這與選項(1)相同,除了提交M
仍然存在,連同其上的分支標簽,並且您有一個指向提交H
的新/不同分支標簽。 您仍需要提醒所有人,但這可能會使他們的工作更輕松。 您可以稍后刪除develop
,當每個人都很好。
(3)恢復合並。 與鏈接文章一樣,讓我們使用W
來表示新的還原提交:
A -- B -- C -- D -- E <-- master
\ \
F - G - H - M - W <-- develop
什么在W
? 無論如何“消除合並的效果”。 在這種情況下,這意味着,在C
和D
執行的任何操作均無法執行。 到目前為止, develop
只有F
, G
和H
的變化。 如果/有人這樣做,問題會在以后發生:
git checkout master
git merge develop
第二個命令根深蒂固地查找master
和develop
被拆分的位置,即提交B
,因此它會從那時起獲取所有更改。 在這一點上,包括W
那些,它們將取消 C
和D
,而不是你想要的。 它可以在之后修復,但是合並的人必須知道這個“刪除C
和D
”定時炸彈等待它們。
請注意,這與“不執行任何操作”選項(0)中的合並相同。 這里的問題是W
的內容 。 在case(0)中,你想要 commit I
的內容,但是在這里你不需要 W
的內容。
考慮到上面顯示的內容,這可以說是最糟糕的選擇,但無論如何我都會列出它:
(4)創建一個包含您要保留的提交副本的全新分支,並將其命名為develop
。 (或者將其命名為其他內容,但之后我們又回到了develop1
的情況,你應該只使用那個。)無論你是保留old-develop
分支,還是放棄它(通過不標記它) ,由你決定,但我會把它畫進去:
F' - G' - H' <-- develop
/
A -- B -- C -- D -- E <-- master
\ \
F - G - H - M <-- old-develop
這包含在您包含的鏈接中。 它只適用於更復雜的情況。
您可以通過將本地分支重置為上一次良好提交來解決此問題,然后推送:
git checkout develop
git reset --hard lastgoodcommit
git push origin develop
請注意,默認情況下,您的上游存儲庫可能會禁止非快進合並。 如果是這樣,您將需要在上游修改該選項,執行上述操作,然后恢復原始設置。
我使用GIT Extensions。 有一個功能可以右鍵單擊UI中的修訂並還原為它。
是的,您可以還原合並,但您需要指定哪個父級是主線。 既然你將開發合並為master,那么這應該可以解決問題:
git revert --mainline 1 HEAD
為了確保你有你想要的東西,你應該用$ lastgoodcommit做差異,但是,$ lastgoodcommit應該是HEAD ^。 這當然是,如果你沒有在合並之上進行提交,如果你有,那么你需要用合並提交替換HEAD。
最后,您還可以通過檢查當前提交之上的代碼來手動還原:
git checkout $lastgoodcommit -- .
' - 。' 有沒有區別於正常結賬,其中HEAD切換到指定的提交,在此處的命令中,工作目錄中的所有文件和暫存區域將與$ lastgoodcommit中的完全相同。 如果你用$ lastgoodcommit做差異,你應該再次看到沒有變化。 基本上它是一個恢復。
您還可以嘗試' git checkout --patch
'來有選擇地還原代碼塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.