Лучше ли объединять «часто» или только после завершения делать большое объединение ветвей функций?

40

Скажем, разрабатываются несколько веток, AиB , а также пошаговый ветвь «исправлена ошибка» C.

Сейчас Cуже «закончен» и объединен в мастера.Aи Bвсе еще находятся в разработке и не будут исправлены до (возможно), когда другая ветвь исправления ошибок будет объединена с главной.

Является ли хорошей идеей Cкак можно скорее объединить новые ветки функций? Чтобы новые функции оставались как можно masterближе? Или лучше позволить новой функции развиваться в их собственном «мире», сливаясь с мастером только после того, как они закончат работу?

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

paul23
источник
5
@gnat, посвященный слиянию ветвей функций в основную строку, мне интересно, хорошо ли объединение основной части с функцией в процессе разработки, чтобы "разрешать конфликты раньше".
paul23
1
@ paul23, я бы сказал, что это практическая необходимость.
Берин Лорич
3
Честно говоря, огромное количество моих проблем с версионностью исчезло, когда я начал использовать в своем коде надлежащий дизайн, такой как изоляция модулей и создание четко определенной модели работы. Если вы слишком много спотыкаетесь о проблемах во время слияний, у вас может быть другая, более серьезная проблема, скрывающаяся где-то. Хороший дизайн невероятно помогает избежать ненужных конфликтов.
Т. Сар - Восстановить Монику
2
Возможно, вы захотите регулярно сливаться с хозяином, чтобы оставаться «достаточно близко», чтобы потом не сделать это слишком болезненным.
Турбьерн Равн Андерсен

Ответы:

71

Чем дольше ветка живет, тем больше она способна отклониться от основной ветви, и чем сложнее, тем сложнее будет окончательное слияние, когда оно будет окончательно завершено. Десять небольших конфликтов легче разрешить, чем один крупный конфликт, и они могут фактически помешать разработчикам дублировать или тратить усилия. Учитывая , что, вы должны слиться masterв Aи Bрегулярно; Один раз в день это довольно распространенная рекомендация, хотя, если у вас много активности в ваших ветках, вы можете объединяться несколько раз в день.

В дополнение к упрощению разрешения конфликтов, вы упомянули Cветку об исправлениях ошибок. Как разработчик, я бы хотел, чтобы в моей ветке были все последние исправления ошибок, чтобы я не повторял поведение, которое привело к ошибке, или писал тесты на основе ошибочных данных.

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

Если вы знаете, что будут конфликты, вы можете выбрать другую стратегию ветвления. Храните несколько изменений в одном и том же файле (файлах) в одной и той же ветке, когда это возможно, и вы уменьшаете или устраняете количество конфликтов. Реорганизовать истории, чтобы они были максимально независимыми, и переработать ветки, возможно, для охвата нескольких историй (ветвь, функция и история не всегда взаимозаменяемы).

mmathis
источник
33
Слияние или перебазирование , поскольку перебазирование часто приводит к более чистой истории коммитов.
Хрилис - на забастовку -
11
@chrylis: Перебазировка может быть опасной, если «ветки охватывают многократные истории» означают, что два разработчика работают над одной веткой.
меритон
9
@meriton из официальных документов: не перебрасывайте коммиты, существующие вне вашего репозитория, и люди могут основываться на них. Если вы будете следовать этому принципу, все будет в порядке. Если вы этого не сделаете, люди будут ненавидеть вас, и вас будут презирать друзья и семья. LOL
Xtreme Biker восстановит Монику
6
@XtremeBiker: ребаз в Git меняет историю. В этом отношении Git работает как в реальной жизни: чтобы изменить историю, вам нужен заговор. В репозитории для самого Git есть ветка, которая регулярно перебазируется, и она очень общедоступна. Причина, по которой это работает, заключается в том, что существует заговор: каждый, кто использует эту ветку, соглашается переписывать историю в определенное время, поэтому они будут уверены, что они в состоянии объединить все к тому времени.
Йорг Миттаг
1
@ paul23 Серьезно подумайте о доставке A и B в новую общую ветку, прежде чем передавать их мастеру. Если они оба являются радикальными изменениями, вы хотите, чтобы они вместе прошли тестирование, прежде чем нанести комбинацию мастеру. Если вы уверены, что можете доставить один непосредственно мастеру, а затем доставить другой в обновленную ветку. Скорее всего, вы захотите посмотреть на исходный код из второй функции, если слияние будет неудачным или вам нужно что-то изменить.
Синк
11

Предполагая, что вы намерены в конечном итоге объединить A, B обратно в master и поддерживать единую кодовую базу, никогда не стоит слишком сильно отклоняться от master. Слишком долгое отклонение от master, особенно когда исправления ошибок и другие разработки сливаются с master, поскольку A, B разрабатываются, безусловно, вызовет конфликты.

Я бы рассмотрел стратегии, аналогичные следующим

  1. Кто бы ни отвечал за A, B должен внимательно следить за мастером и объединяться в любых изменениях.
  2. Еще лучше, если у вас есть автоматизация сборки и тестирования, убедитесь, что A, B объединены в master, и проходите тесты каждую ночь.
  3. Исходя из вашего комментария к другому ответу, кажется, что A, B может занять некоторое время, чтобы развиться. В этом случае вы можете даже подумать о том, чтобы A, B также слились друг с другом, так что в итоге у вас не возникнет серьезных проблем при объединении обоих обратно в master.
  4. На более высоком уровне подумайте, зачем вам нужны 2 отдельные линии долгой разработки. Не могли бы вы разбиться на более мелкие слияния? Не могли бы вы разбить на отдельные микро сервисы?
kenchew
источник
5

Обычно часто лучше, чем массивный.

Меньшие, более частые запросы на тягу почти всегда лучше.

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

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

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

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

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

Марк Роджерс
источник
1
Флаги функций могут быть дорогостоящими (450 миллионов долларов США за 45 минут). Этот пример также упоминается дядей Бобом (но без каких-либо технических аспектов (как и следовало ожидать)).
Питер Мортенсен
1
Да, есть в конечном итоге удаление их, хотя обычно это не так сложно. Можно поддерживать их дольше, но тогда флаг обеспечивает более широкое использование. Я согласен, если все сделано случайно или без последующих действий, тогда все может пойти плохо. Однако, когда большой запрос на получение доступа становится трудным для рассмотрения, дела могут пойти плохо. С другой стороны, некоторые люди могут не иметь возможности добавлять что-то вроде флага конфигурации в приложение, с которым они работают. Как правило, это помогает с UAT и развертыванием функции.
Марк Роджерс
3

В «Рефакторинге» Мартина Фаулера совет, который он дает, никогда не позволяет ветке отделяться от хозяина дольше, чем на один день. IIRC, вы должны внести небольшое изменение, проверить, чтобы убедиться, что вы ничего не сломали, а затем объединить его обратно.

JohnnyApplesauce
источник
2
Ну Aи Bпроведите принципиально новые радикальные пересмотры того, как работает приложение, они не «делаются» в течение месяца. Однако они также бесполезны, прежде чем они будут сделаны ...
paul23
8
Они не могут быть бесполезными до того, как они будут сделаны - они обеспечивают ценность, являясь шагом к полному результату и сокращая работу, требуемую в будущем. Используя такие методы, как переключение функций, ветвление за абстракцией или простое выполнение части интерфейса пользователя, можно безопасно объединить незавершенную работу с мастером.
bdsl
1
вот почему перебазирование вашего локального поверх любых изменений в основной ветке удобно для более долгосрочной разработки. Сохраняет вашу работу, как если бы она была только что
обновлена
2

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

Qwertie
источник
1
Флаги функций = код зомби (до воскресения)?
Питер Мортенсен
@PeterMortensen Ну, вы должны стремиться удалить флаги как можно скорее, но это может сработать в определенных ситуациях
Qwertie
3
@PeterMortensen нет, если флаг включен хотя бы для одного человека
Ян