Повторное повторное слияние в Git

У меня возникла проблема: у меня была ветвь 28s для конкретной задачи в Git, которую я объединил в общем ветки develop. Оказывается, я сделал это слишком быстро, поэтому я использовал git -revert, чтобы отменить слияние. Однако теперь пришло время объединить 28s в develop, но команда git -merge видит исходное слияние и счастливо объявляет, что все хорошо, а ветки уже объединены. Что мне теперь делать? Создайте "Revert" Revert "28s → develop" "commit"? Кажется, это не лучший способ сделать это, но я не могу представить ни одного другого на данный момент.

Как выглядит древовидная структура:

Git log output

128
задан Toms Mikoss 03 июля '09 в 10:15
источник поделиться

5 ответов

Вам нужно "вернуть реверс". В зависимости от того, как вы это сделали, это может быть не так просто, как кажется. Посмотрите официальный документ в этом разделе.

---o---o---o---M---x---x---W---x---Y
              /
      ---A---B-------------------C---D

чтобы разрешить:

---o---o---o---M---x---x-------x-------*
              /                       /
      ---A---B-------------------C---D

Но все ли работает? Конечно. Вы можете вернуть слияние, и из чисто технический угол, git сделал это очень естественно и не имел реального неприятности.
Он просто считал это изменением от "состояния до слияния" до "state after merge", и все. Ничего сложного, ничего странного, ничего действительно опасного. git сделает это, даже не подумав об этом.

Итак, с технической точки зрения, нет ничего плохого в возврате слияния, но из угла рабочего процесса это то, что вы обычно должны пытаться избежать.

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

  • разделите проблему на ветку, которую вы объединили, и просто исправьте ее,
  • или попытайтесь вернуть индивидуальную фиксацию, вызвавшую ее.

Да, это сложнее, и нет, это не всегда будет работать (иногда ответ: "Упс, я действительно не должен был сливать его, потому что это не было все еще готово, и мне действительно нужно отменить все слияние" ). Итак, вы действительно должен вернуть слияние, но если вы хотите повторно выполнить слияние, вы теперь нужно сделать это, возвращая возврат.

103
ответ дан J-16 SDiZ 03 июля '09 в 10:35
источник поделиться

Предположим, что у вас есть такая история

---o---o---o---M---W---x-------x-------*
              /                      
      ---A---B

Где A, B не удалось зафиксировать, а W - вернуть M

Итак, прежде чем я начну исправлять найденные проблемы, я делаю вишневый выбор W для моей ветки

git cherry-pick -x W

Затем я возвращаю W commit на моей ветке

git revert W 

После этого я могу продолжить исправление.

Последняя история может выглядеть так:

---o---o---o---M---W---x-------x-------*
              /                       /     
      ---A---B---W---W`----------C---D

Когда я отправляю PR, он ясно покажет, что PR отменяет возврат и добавляет новые коммиты.

29
ответ дан Maksim Kotlyar 26 марта '13 в 23:21
источник поделиться

Чтобы вернуть реверс, не слишком сильно закручивая рабочий процесс:

  • Создайте локальную копию мусора для разработки
  • Отменить повторную фиксацию на локальной копии разработки
  • Слейте эту копию в свою ветку функций и нажмите на свою ветку функций на свой сервер git.

Теперь ваша ветка функций должна быть объединена как обычно, когда вы к ней готовы. Единственным недостатком здесь является то, что у вас будет несколько дополнительных слияний/повторов в вашей истории.

2
ответ дан Sam Dufel 22 мая '17 в 21:32
источник поделиться

Вместо использования git-revert вы могли бы использовать эту команду в ветке devel для выбросить (отменить) неправильную фиксацию слияния (вместо того, чтобы просто вернуть ее).

git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE

Это также соответствующим образом отрегулирует содержимое рабочего каталога. Будьте осторожны:

  • Сохраните изменения в ветке разработки (с неправильного слияния), потому что они также будет стираться с помощью git-reset. Все фиксации после того, что вы указываете как аргумент git reset исчезнет!
  • Кроме того, не делайте этого, если ваши изменения уже были вытащены из других репозиториев потому что reset будет переписывать историю.

Я рекомендую внимательно изучить man-страницу git-reset, прежде чем пытаться это сделать.

Теперь, после reset, вы можете повторно применить свои изменения в devel, а затем сделать

git checkout devel
git merge 28s

Это будет реальное слияние от 28s в devel, как и исходное (которое теперь стирается из истории git).

2
ответ дан knweiss 05 июля '09 в 17:29
источник поделиться

Я только что нашел этот пост, столкнувшись с той же проблемой. Я нахожу это выше, чем страшно, чтобы сделать reset hards и т.д. Я в конечном итоге удалю то, чего я не хочу, и не смогу вернуть его.

Вместо этого я проверил фиксацию, я хотел, чтобы ветка вернулась, например. git checkout 123466t7632723. Затем преобразуется в ветвь git checkout my-new-branch. Затем я удалил ветку, в которой я больше не хотел. Конечно, это будет работать, только если вы сможете выбросить ветку, которую вы испортили.

1
ответ дан Nicola 13 нояб. '17 в 13:34
источник поделиться

Другие вопросы по меткам