@karpo518

Как отменять коммит слияния, чтобы потом без проблем выполнить повторное слияние?

Если выполнить revert коммита слияния, то при следующем слиянии ни один коммит до предыдущего слияния не применится в целевой ветке, потому что эти коммиты уже есть в целевой ветке, но перезаписаны revert коммитом. Как без проблем отменять слияние и после фикса применять его повторно? Делать revert revert коммита слияния? Или есть какой-то более грамотный способ?
  • Вопрос задан
  • 171 просмотр
Решения вопроса 2
Такие вопросы стоит задавать тимлиду или сразу всей команде чтобы понимать как это принято в конкретном проекте.

Самый гладки способ - после выявления проблемы создавать уже новую ветку от целевой. В этой новой ветке делать реверт реверта, и поверх этого фиксить проблемы. Такие изменения можно будет без конфликтов отправить в целевую ветку через новый мерж реквест.

Учитывая что речь про дев, согласовав с командой, можно без ревертов, через rebase снести проблемные комиты, и накатить вместо них рабочие.
Ответ написан
Комментировать
sergey-kuznetsov
@sergey-kuznetsov Куратор тега Git
Автоматизатор
Линус Торвальдс уже подробно комментировал подобную ситуацию.

И вы совершенно правильно всё поняли. Реверс коммита слияния восстанавливает код, который был изменён этим коммитом, но ничего не делает с эффектами, которые это слияние оказало на историю. Слияние всё ещё будет существовать, и оно всё ещё будет восприниматься как объединение двух веток, и будущие слияния будут воспринимать это слияние как последнее общее состояние — и реверт никак на это не повлияет.

Таким образом, «revert» отменяет изменения кода, но это совсем не «undo» в том смысле, что он не отменяет влияния коммита слияния на историю репозитория.

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

Но есть ещё один способ — можно по-настоящему отменить слияние, пересобрав тематическую ветку заново. Тогда не придется делать повторный revert.

Давайте вернемся к вашей ситуации:
 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E   <-- доработанная ветка задачи

Где M — это слияние, которое вносит эти преждевременные изменения в основную ветку, x — это изменения не связанные с тем, что сделала тематическая ветка и уже внесённые в основную, а W - это «реверт M» (разве W не выглядит как перевернутое M?)

Мы можем пересобрать тематическую ветку заново

$ git rebase --no-ff P

Получим:
   A'---B'---C'------------D'---E'  <-- пересозданная тематическая ветка
  /
 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E

Теперь можно слить пересозданную ветку с основной, не откатывая коммит W, и история основной ветки будет выглядеть так:
   A'---B'---C'------------D'---E'
  /                              \
 P---o---o---M---x---x---W---x---M2
  \         /
   A---B---C

Правда такой трюк не сработает, если вы успели до слияния пообновлять тематическую ветку из основной. Эти коммиты слияния намертво свяжут две цепочки коммитов и не дадут сделать rebase.

Но если обсуждать именно грамотный способ работы, то не стоит возвращаться в тематическую ветку после того, как она уже слита с основной. Ветка задачи всегда удаляется сразу после слияния, а все доработки и исправления делаются уже в новой ветке, как правильно заметил Дмитрий Гординский в соседнем ответе.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы