
Итак, я совершил довольно большую ошибку. Я сделал коммит, вытащил, объединил (но испортил код при этом), а затем отправил. Я хотел бы переделать это слияние и привести код в порядок. Есть ли способ это сделать?
Я использую битбакет.
решение1
Не уверен, что это «благословенный» способ, но вот что я сделал, чтобы решить ту же проблему без «принудительного нажатия» или чего-то подобного.
Предположим, что ваша история выглядит примерно так (и M — это неудачное слияние):
-A--B--C--M (master points here)
\ /
D----E
Запуск git checkout -b merge_fix <commit ID E>
создает ветвь до того, как мы допустили какие-либо ошибки:
-A--B--C--M (master points here)
\ /
D----E (HEAD and merge_fix point here)
Теперь давайте повторим слияние на нашей новой ветке. Мы не можем просто слить в master
, поэтому нам нужно вручную выбрать коммит перед нашим плохим слиянием: git merge <commit ID C>
Не совершайте тех же ошибок, что и в прошлый раз!
-A--B--C--M (master points here)
\ X
D----E-G (HEAD and merge_fix point here)
Предполагая, что коммит G
выглядит хорошо, теперь мы хотим синхронизироваться с вершиной ветки master
. Эта команда сообщает git игнорировать изменения, которые были сделаны в master, и принудительно сделать наши изменения результатом слияния:git merge -s ours master
-A--B--C--M (master points here)
\ X \
D----E-G--H (HEAD and merge_fix point here)
Наконец (опять же, предполагая, что коммит H
выглядит хорошо), мы хотим выполнить ускоренную перемотку вперед, master
чтобы включить наше исправленное слияние:
git checkout master
git merge merge_fix
На самом деле это просто перемещает master
указатель ветки в H
, но я воспользуюсь возможностью немного подчистить свой ASCII-арт:
-A--B--C--M--H (HEAD, master, and merge_fix all point here)
\ X /
D----E--G
И вот оно! Вы успешно повторили слияние, не нарушив при этом историю!
решение2
Это можно сделать вот так:
- Сбросьте до коммита, который был до слияния.
- Повторите слияние.
- Силовой толчок
То есть:
git reset --hard SHA1
git merge branchname
git commit
git push --force remotename branchname
Просто имейте в виду, что это git push --force
приведет к переписыванию всего, что было у вас в удаленной ветке, и это может повлиять и на других людей, использующих эту ветку. (Обычно этого делать не следует.)
решение3
git merge --abort
и затем вы можете снова объединить
решение4
У меня была другая, несколько более сложная установка.
по сути есть три отправные точки: (а все остальные решения предполагают либо 1, либо 2)
redo-branch
должны быть полностью объединены И
после слиянияredo-branch
былиникаких других слиянийredo-branch
должны быть полностью объединены И
после слиянияredo-branch
уже былидругие слияния, который должен быть сохраненredo-branch
этодолгоживущая ветвьбыть многократно объединенным И
только диапазон пересмотрабылчасть слиянияИ
былидругие коммиты/слияния на главномпосле неудачного слияния (ой)
настройка для (3) будет
---A--B--C--M (master points here)
/ /
-X--D-----E--Y (that's the long-living redo-branch)
- у вас должно быть все в порядке с решениемhttps://superuser.com/a/691497/308385
- то же решение, что и 1, может сработать
- Давайте начнем :-)
# let's start on the last commit before the failed merge
git checkout redo-branch
git checkout -b D^1 new-branch-for-merge
# now let's pick all the revisions D through E
git cherry-pick D^1..E
# go to the target branch (master) and merge
git checkout master
git merge new-branch-for-merge