Удаление функций из выпусков в Git Flow

Я работаю над командой с большой базой Java-кода (300k + строк кода), которая недавно приняла Git в качестве исходного элемента управления (перенесена из ClearCase). Мы используем Git Flow как нашу стратегию ветвления. Есть несколько вариантов использования, с которыми мы сталкиваемся довольно часто, с которыми мы боролись.

  • Мы объединили все наши функции в ветку разработки, которая будет использоваться в предстоящем выпуске. Когда мы приближаемся к релизу, оказывается, что одна функция не может жить (из-за того, что клиент не готов или какая-то другая причина). Какой лучший способ создать ветвь релиза, но оставьте конкретную функцию (во многих коммитах)? Эта функция должна быть доступна для включения в следующий будущий выпуск. То, что мы пробовали раньше, состоит в том, чтобы сделать "git revert" для всех коммитов, создать ветвь освобождения, а затем выполнить "git revert" на отмененных фиксациях. Это довольно болезненный подход, особенно для больших возможностей.

  • Мы уже создали ветвь релиза, но до того, как релиз идет в прямом эфире, он решил, что функция должна быть удалена. Подобно первому варианту использования, эта функция должна иметь возможность перейти к следующей версии. Из-за этого просто выполнение "git revert" в коммитах полностью не разрешает его, так как возврат будет сгенерирован обратно в ветвь разработки, когда мы закончим выпуск < git.

Как указано в модели Git Flow, все фиксации производятся на ветвях функций и никогда не находятся непосредственно на ветке разработки. Когда функция завершена и готова к следующей версии, она затем объединяется для разработки. Когда придет время для следующего выпуска, ветвь релиза создается без разработки. После того, как релиз был протестирован с регрессией и, при необходимости, исправлен, он переходит к производству и объединяется с мастером, а затем развивается в случае исправлений ошибок и помечен номером версии. Проблемы выше, когда функция, которая, как мы думали, идет в следующем выпуске, заканчивается тем, что ее нужно оставить без внимания.

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

Ответ 1

В Git объединение слиянием делает две вещи. Во-первых, он создает историю слияния, поэтому Git знает, что было объединено и что не было объединено. А во-вторых, он объединяет изменения двух разных направлений совместной работы.

Вы можете обмануть Git в обоих этих отношениях, и это то, что звучит так, как вам нужно. Существует два способа создания истории слияния без сохранения изменений

git merge --strategy=ours 

и

git merge
git revert -m 1 MERGE_SHA

Первый создает фиксацию слияния (и историю слияния), но оставляет все изменения, которые обычно были объединены. Позднее создается слияние (и история слияния) и сливается в изменениях, но затем сразу удаляется все изменения при сохранении первой истории.

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

Итак, представьте, что у вас есть ветвь trouble, которая содержит 6 коммитов (1-6), и вам нужно объединить trouble в master, но вы не хотите объединять изменения, внесенные в Commit 4. Вместо git merge trouble вы бы сделали

git merge 3 # merges 1/2/3
git merge -s ours 4 # creates merge history for 4, but does NOT merge any changes from 4 
git merge trouble # merges 5/6

Ответ 2

Я боролся с тем же вопросом. Возможно, здесь ключевой момент заключается в том, чтобы не использовать git-flow 'release finish' для предотвращения обратного слияния в разработке.

Идея была бы:

  • Объединяйся, чтобы развиваться как обычно
  • Оставьте открытыми ветки функций, пока они не объединятся в мастер
  • Ветвь из предыдущей ветки выпуска и объединение всех функциональных ветвей, которые будут выпущены там, при подготовке к следующей версии
  • используйте revert в выпуске и развивайте ветку, чтобы удалить все функции, которые нужно исключить