Подтвердить что ты не робот

Git: как вернуть слияние ветвей без перезаписи истории?

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

git checkout master
git merge opengl
git push

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

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

Спасибо.

4b9b3361

Ответ 1

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

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

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

Ответ 2

Изменить: Это не то, о чем попросил ОП, но я сохраню его здесь, если кто-то захочет найти решение, которое связано с переписыванием истории.


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

git branch erroneousMerge master

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

Затем reset master, чтобы ссылаться на последнюю фиксацию перед слиянием; скажем, что он совершает e498b2...:

git checkout e498b2
git branch -f master

Теперь вы можете нажать скорректированный master (-f означает, что вы хотите сделать сервер reset его ветвью 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 для их восстановления.