Git стратегия резервного копирования исправлений в старые ветки (вишня-выбор против слияния) - программирование
Подтвердить что ты не робот

Git стратегия резервного копирования исправлений в старые ветки (вишня-выбор против слияния)

В нашей команде мы работаем следующим образом:

  • У нас есть только ветвь master в нашем репозитории GitHub, она нестабильна - думает, что ее туда нажимают; для стабильных выпусков мы используем теги (для разработки мы используем частные вилки на GitHub)
  • мы выпускаем новую небольшую версию каждые 3 недели, в которой содержатся исправления и новые функции (скажем, 1.2.4, 1.2.5, 1.2.6...)
  • мы также должны поддерживать каждую младшую старую версию в течение ограниченного времени (несколько месяцев), поэтому, когда кто-то использует 1.2.4, а самая новая версия - 1.2.7, и они находят ошибку, они могут просить нас исправить ошибку на ветке, которую они используют. Затем мы выпускаем версию патча 1.2.4A.
  • исправления являются весьма исключительными. Обычно мы делаем не более 1-2 патчей для младшего выпуска. Для большинства выпусков мы не делаем патчи.

Вопрос в том, какая лучшая стратегия исправить ошибку на главном и старом ветки одновременно?

Я могу думать о двух основных стратегиях:

  • Исправьте ошибку на master, затем проверьте v1.2.4, затем cherry-pick соответствующую фиксацию (предположим, что исправление является одной фиксацией, которая всегда выполняется) и пометьте полученное коммит как v1.2.4A.

  • Оформить заказ v1.2.4, исправить ошибку и зафиксировать, пометить фиксацию как v1.2.4A и включить ее в master, выполнить слияние.

Я скорее одобряю первую версию (вишневый сбор), но я хотел бы услышать другие комментарии о плюсах и минусах.

Конечно, все может усложниться, когда коммиты в середине вносят некоторые существенные изменения, которые могут привести к тому, что невозможно создать фиксацию, которая будет работать как в 1.2.4, так и в master (например, при изменении имени какой-либо функции или более сложных вещей). Но более распространенная ситуация заключается в том, что исправление может быть перенесено без проблем.

Преимущества сбора вишни у мастера:

  • Я думаю, что история более "съедобна" с использованием вишни. Рассмотрим это:

    | <- bugfix done on master
    |
    |
    | <- v1.2.7
    ...
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |  - <- v.1.2.4A (cherry-picked from master)
    | / 
    | <- v1.2.4
    

    vs this:

    | <- bugfix merged to master
    |\ 
    | \
    |  |
    |  |   <- v1.2.7
    ...
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  - <- v.1.2.4A (direct bugfix)
    | / 
    | <- v1.2.4
    

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

  • Скажем, я исправил проблему на v1.2.4, но через несколько дней кто-то попросит меня запланировать на v1.2.3. Cherry-pick - самый разумный способ сделать это.

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

4b9b3361

Ответ 1

В проектах с открытым исходным кодом, над которыми я работал, консенсус, похоже, заключается в том, что исправления должны сначала приземлиться на мастер, протестировать их и только после этого вернуться к более старым версиям. Вы можете видеть это в том, как ядро ​​Linux делает стабильные версии, например: разработчики представляют патчи для mainline, но также назначают их для включения в стабильную.

Когда вы выбрали вишню в этой ситуации, вы, вероятно, захотите использовать флаг -x:

При записи фиксации добавьте строку, в которой говорится: "(вишня выбрана from commit...)" в исходное сообщение фиксации, чтобы укажите, какие из этих изменений были выбраны из вишни. Это сделано только для черешни без конфликтов.... [Если] вы выбираете вишню между двумя видимыми видимыми ветвями (например, backporting исправление для ветки обслуживания для более старой версии от ветвь разработки), добавление этой информации может быть полезно.

Ответ 2

Ваша стратегия 2, сначала исправление ошибки в предыдущей ветки освобождения, например. v1.2.4, а затем слияние этого изменения в ваш соединитель развития предлагается gitworkflows (7):

Правило: ветки раздела

Создайте боковую ветвь для каждой темы (функция, исправление,...). Откроем его на самой старой ветке интеграции, которую вы в конечном итоге захотите объединить. [выделено мной]

Многое может быть сделано очень естественно:

Чтобы получить свойство /bugfix в ветку интеграции, просто слейте его. Если тема развивается еще тем временем, снова сливайтесь. (Обратите внимание, что вам не обязательно сначала объединять его с самой старой ветвью интеграции. Например, сначала вы можете объединить исправление, дать ему некоторое время тестирования и слить в maint, когда вы знаете, что он стабилен.)

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

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

Обе стратегии жизнеспособны, и каждый из них имеет преимущества.