Снятие слияния Git
Возьмем следующий случай:
У меня есть какая-то работа в ветке темы, и теперь я готов вернуться к мастеру:
* eb3b733 3 [master] [origin/master]
| * b62cae6 2 [topic]
|/
* 38abeae 1
Я выполняю слияние с мастером, разрешаю конфликты и теперь у меня:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | eb3b733 3 [origin/master]
|/
* 38abeae 1
Теперь для слияния потребовалось некоторое время, поэтому я делаю еще один выбор и замечаю, что ветвь удаленного мастера имеет новые изменения:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
| | * e7affba 4 [origin/master]
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Если я попробую 'git rebase origin/master' от master, я вынужден снова разрешить все конфликты, а также потеряю фиксацию слияния:
* d4de423 2 [master]
* e7affba 4 [origin/master]
* eb3b733 3
| * b62cae6 2 [topic]
|/
* 38abeae 1
Есть ли чистый способ переустановить фиксацию слияния, поэтому я получаю историю, подобную той, которую я показываю ниже?
* 51984c7 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | e7affba 4 [origin/master]
* | eb3b733 3
|/
* 38abeae 1
Ответы
Ответ 1
Здесь есть два варианта.
Один из них состоит в том, чтобы сделать интерактивную перезагрузку и отредактировать фиксацию слияния, повторить слияние вручную и продолжить rebase.
Другим является использование опции -p
на git rebase
, которая описана в следующем руководстве: "Вместо того, чтобы игнорировать слияния, попробуйте воссоздать их". Этот вопрос далее объясняет это: Что именно делает git 'rebate -preserve-merges " do (и почему?)
Ответ 2
Хорошо, что старый вопрос и он уже принял ответ @siride
, но этого ответа было недостаточно в моем случае, поскольку --preserve-merges
силы вы разрешаете все конфликты во второй раз. Мое решение основано на идее @Tobi B
, но с точными пошаговыми командами
Итак, мы начнем с такого состояния на примере в вопросе:
* 8101fe3 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
| |
| | * f5a7ca8 5 [origin/master]
| | * e7affba 4
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Обратите внимание, что у нас есть 2 фиксации впереди мастера, поэтому вишневый захват не будет работать.
-
Прежде всего, создайте нужную нам историю:
git checkout -b correct-history # create new branch to save master for future
git rebase -s ours -p origin/master
-p
означает --preserve-merges
, мы используем его для сохранения фиксации слияния в истории
-s ours
означает --strategy=ours
, мы используем его для игнорирования всех конфликтов слияния, поскольку нам не важно, какое содержимое будет в этом объединении, нам нужна только хорошая история.
История будет выглядеть так (игнорирование мастера):
* 51984c7 Merge branch 'topic' [HEAD -> correct-history]
|\
| * b62cae6 2 [topic]
* | f5a7ca8 5 [origin/master]
* | e7affba 4
* | eb3b733 3
|/
* 38abeae 1
-
Теперь дайте правильный индекс.
git checkout master # return to our master branch
git merge origin/master # merge origin/master on top of our master
Здесь могут возникнуть дополнительные конфликты слияния, но это будут только конфликты из файлов, измененных между 8101fe3
и f5a7ca8
, но не включающие уже разрешенные конфликты из topic
История будет выглядеть так (игнорируя правильную историю):
* 94f1484 Merge branch 'origin/master' [HEAD -> master]
|\
* | f5a7ca8 5 [origin/master]
* | e7affba 4
| * 8101fe3 Merge branch 'topic'
| |\
| | * b62cae6 2 [topic]
|/ /
* / eb3b733 3
|/
* 38abeae 1
-
Последний этап - совместить нашу ветку с правильной историей и ветвью с правильным индексом
git reset --soft correct-history
git commit --amend
Мы используем reset --soft
to reset нашу ветку (и историю) для исправления истории, но оставляем индекс и рабочее дерево как есть. Затем мы используем commit --amend
для перезаписи нашего слияния, который имел неправильный индекс, с нашим хорошим индексом от master.
В конце мы будем иметь такое состояние (обратите внимание на другой идентификатор верхней фиксации):
* 13e6d03 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
* | f5a7ca8 5 [origin/master]
* | e7affba 4
* | eb3b733 3
|/
* 38abeae 1
Ответ 3
Учитывая, что я просто потерял день, пытаясь понять это и фактически нашел решение с помощью коллеги, я думал, что должен перезвонить.
У нас есть большая база кода, и нам приходится иметь дело с 2-мя ветвями, которые в то же время изменяются. Существует основная ветвь и вторичная ветка, если вы, который.
Пока я объединяю вторичную ветвь в основную ветвь, работа продолжается в основной ветке, и к моменту завершения я не могу выдвигать свои изменения, потому что они несовместимы.
Поэтому мне нужно "переустановить" мое "слияние".
Так мы наконец это сделали:
1) обратите внимание на SHA. пример: c4a924d458ea0629c0d694f1b9e9576a3ecf506b
git log -1
2) Создайте правильную историю, но это сломает слияние.
git rebase -s ours --preserve-merges origin/master
3) обратите внимание на SHA. пример: 29dd8101d78
git log -1
4) Теперь reset, где вы были раньше
git reset c4a924d458ea0629c0d694f1b9e9576a3ecf506b --hard
5) Теперь объедините текущий мастер в свою рабочую ветвь
git merge origin/master
git mergetool
git commit -m"correct files
6) Теперь, когда у вас есть нужные файлы, но неправильная история, получите право
историю в верхней части вашего изменения с помощью:
git reset 29dd8101d78 --soft
7) И затем - отмените результаты в исходном коммитете
git commit --amend
Voila!
Ответ 4
Похоже, что вы хотите удалить свое первое слияние. Вы можете выполнить следующую процедуру:
git checkout master # Let make sure we are on master branch
git reset --hard master~ # Let get back to master before the merge
git pull # or git merge remote/master
git merge topic
Это даст вам то, что вы хотите.
Ответ 5
- Из вашей фиксации слияния
- Черри - выберите новое изменение, которое должно быть легким.
- скопируйте свои материалы.
- повторить слияние и разрешить конфликты, просто скопировав файлы из вашей локальной копии;)