Git: как отменить слияние веток без перезаписи истории? - PullRequest
17 голосов
/ 21 марта 2011

У меня есть две ветви: master и opengl. Я недавно закончил реализацию (или, по крайней мере, так думал) ветки opengl и решил объединить ее в master:

git checkout master
git merge opengl
git push

После того, как я это сделал, несколько разработчиков, работающих над веткой master, извлекли мои изменения, и оказалось, что моя реализация вступила в конфликт с некоторым их кодом. Поэтому я хотел бы отменить операцию слияния в ветви master, но без перезаписи истории.

Обратите внимание, что я хотел бы иметь возможность слить ветку opengl в master в конце концов (после того, как я исправлю все ошибки). Поэтому просто проверить более старую версию master и зафиксировать ее не получится - вновь созданный коммит отменит мои изменения с opengl, когда я попытаюсь объединить ее.

Спасибо.

Ответы [ 2 ]

18 голосов
/ 16 ноября 2012

Документация " Как отменить ошибочное слияние ", упомянутое cebewee , объясняет, почему Git Revert является хитрым при возврате слияния.

Таким образом, объединение все еще будет существовать , и оно все равно будет рассматриваться как объединение двух ветвей, и будущие объединения будут рассматривать это объединение как последнее общее состояние - и обратный процесс, который отменил объединение, принес это никак не повлияет на это.
Если вы думаете о «возврате» как об «отмене», то вы всегда будете пропускать эту часть возвратов.
Да, он отменяет данные, но нет, он не отменяет историю.

git revert является правильным решением, но в будущем оно будет иметь последствия, когда вы захотите снова объединить эту ветвь.
Следующее слияние затем должно сначала «отменить возврат», а затем слить ветку.

4 голосов
/ 22 марта 2011

Редактировать: Получается, что не - это то, о чем просил ОП, но я оставлю это здесь на случай, если кто-то должен будет найти решение, которое включает переписывание истории.


Сначала создайте новую ветку, если вы хотите сохранить коммит слияния локально, чтобы коммит не "исчезал" после перемещения master:

git branch erroneousMerge master

Если другие разработчики также сделали коммиты после ошибочного слияния, они тоже должны это сделать!

Затем сбросить master, чтобы обратиться кпоследний коммит перед слиянием;скажем, это коммит e498b2...:

git checkout e498b2
git branch -f master

Теперь вы можете нажать исправленный master (-f означает, что вы хотите, чтобы сервер сбросил свою ветвь master на коммит, которыйвы указали на это, хотя этот коммит является предком того, на который он указывает в репозитории):

git push -f origin master

Теперь другие разработчики могут обновить свои master, чтобы они соответствовалисервер (-f указывает, что они принимают, что ветвь сместилась назад):

git fetch -f origin master:master

Если другие разработчики внесли изменения после ошибочного слияния (скажем, что слияние зафиксировано abc123, ониможно использовать rebase, чтобы переместить изменения в исправленные master:

git rebase --onto master abc123 oldMaster

Если вы облажались в какой-то момент и в итоге получили «проигрышные» коммиты, потому что больше нет веток, указывающих на нихВы можете использовать git fsck --lost-found для их восстановления.

...