Стратегия просмотра кода перед слиянием с мастером из функциональных веток

22

Я и моя команда используем функциональные ветви (с git). Мне интересно, какая стратегия лучше всего подходит для проверки кода перед слиянием с мастером.

  1. Я извлекаю новую ветку от мастера, давайте назовем ее fb_ # 1
  2. Я совершаю несколько раз, а затем хочу объединить его с мастером
  3. Перед слиянием кто-то должен сделать обзор кода

Теперь есть 2 возможности:

первый

  1. Я объединяю master с fb_ # 1не fb_ # 1 с master), чтобы сделать его как можно более современным
  2. Товарищ по команде рассматривает изменения между главной головой и головой fb_ # 1
  3. Если fb_ # 1 в порядке, мы объединяем fb_ # 1 с мастером
  4. Плюсы: нет устаревшего кода в обзоре
  5. Минусы: если кто-то еще сливает что-то между "1" и "2" его изменения появляются в обзоре, хотя они принадлежат другому обзору.

второй

  1. Товарищ по команде просматривает изменения между точкой извлечения (git merge-base master fb_ # 1) и головой fb_ # 1
  2. Плюсы: мы видим, что именно изменилось во время работы над веткой функций
  3. Минусы: в обзоре может появиться устаревший код.

Какой путь вы считаете лучше и почему ? Может быть, есть другой более подходящий подход?

Анджей Гис
источник

Ответы:

9

Есть вариант вашего первого варианта:

  1. объединить мастер с fb_ # 1 (не fb_ # 1 с мастером), чтобы сделать его как можно более современным
  2. Товарищ по команде просматривает изменения между мастером в точке, где вы слились, и головой fb_ # 1
  3. Если fb_ # 1 в порядке, мы объединяем fb_ # 1 с мастером
  4. Быстрая проверка, что слияние в порядке

например.

... ma -- ... -- mm -- ... -- mf  <- master
      \            \         /
       f1 ... fn -- fm -----      <-- fb_#1

где:

  • ма является предком хозяина и fb_ # 1.
  • fn - последнее изменение в вашей ветке
  • mm - это коммит, который был master / HEAD на момент объединения с вашей веткой (давая fm ).

Итак, вы сравниваете mm и fm в своем первоначальном обзоре, а затем быстро проверяете после слияния обратно mf, чтобы убедиться, что ничего не изменилось на мастере во время шагов 1-3. Кажется, в этом есть все плюсы и минусы для первоначального обзора.

Это предполагает, что обзор выполняется быстрее по сравнению с обычной частотой изменений, переданных мастеру, поэтому fm -> mf часто бывают ускоренными.

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

Бесполезный
источник
Как мне получить "точку, которую вы слили"? Будет ли «git merge-base master head» нормально, или он покажет начальную точку ветвления?
Анджей Гис
Если вы не намеренно обновите мастер после слияния, он будет просто мастером.
бесполезно
Да, но как получить эту точку, если кто-то еще обновляет ее?
Анджей Гис
Когда вы находитесь на ветке fb, используйте git show HEAD. Поскольку это будет коммит слияния fm , в нем будут перечислены оба родителя. Итак, у вас есть хеш мм . Кроме того, вы можете тривиально увидеть родителя в gitkлюбом другом git-браузере
Бесполезно
13

третий

  • Вы перебазируете ветку на master, чтобы обновлять ее и хранить изменения отдельно.

    Это создает новую историю отрасли. Это будут новые ревизии с новыми идентификаторами, которые будут иметь такое же содержимое, но будут получены из последней версии мастера и не будут ссылаться на старые ревизии. Старые ревизии по-прежнему доступны в «reflog», если вам нужно сослаться на них, например, потому что вы обнаружили, что допустили ошибку при разрешении конфликта. Кроме того, они бесполезны. Git по умолчанию сокращает журнал после 3 месяцев и удаляет старые ревизии.

  • Вы используете интерактивное перебазирование ( git rebase -iи git commit --amend), чтобы изменить порядок, отредактировать и очистить изменения, чтобы каждое из них сделало логически закрытое изменение.

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

  • Плюсы:

    • нет устаревшего кода в обзоре
    • мы видим, что именно изменилось во время работы над веткой функций
  • Минусы:
    • немного больше работы
    • Вы должны позаботиться о том, чтобы не перебазировать что-либо, что уже объединено или что вы поделились, и получатель не ожидает, что это будет перемотано.

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

Это то, что делают Linux и Git. И нет ничего необычного в том, что серии из 20-25 патчей представляются на рассмотрение и несколько раз переписываются в этих проектах.

На самом деле Linux делал это с самого начала в проекте, когда они выбирали тарболы и патчи. Когда много лет спустя Линус решил создать git, это было основной причиной реализации rebaseкоманды и ее интерактивного варианта. Также из-за этого у git раздельное представление об авторе и коммиттере . Автор - это тот, кто первым создал ревизию, а автор, который последним коснулся ее. Поскольку и в Linux, и в Git патчи по-прежнему отправляются по электронной почте, они почти никогда не являются одним и тем же человеком.

Ян Худек
источник
1
+1 также ОП не спрашивал о следующих шагах, но чтобы получить свою функцию в мастере, вы могли бы использовать merge --no-ff
символ,
@stijn: --no-ffимеет свои плюсы и минусы. Я лично нахожу это больше шума чем что-либо. YMMV.
Ян Худек
да, это вопрос предпочтений. Если мастер, как правило, чистый и прямой, я не против больших функций, имеющих отдельный «пузырь». Если мастер уже в беспорядке, no-ff только усугубляет ситуацию
stijn
Хотел бы я принять режим, чем один ответ. Гибридное решение было бы идеальным. Использование rebase и сравнение с точкой ветвления представляется наилучшим способом.
Анджей Гис
Второй довод - я не думаю, что вы можете сделать это, если вы уже поделились своей веткой с кем-либо. При переписывании истории будут несоответствия.
sixtyfootersdude
4

На самом деле существует третья возможность - и, скорее всего, множество других, поскольку GIT - это скорее реализация структуры SCM, чем реализация методологии SCM. Эта третья возможность основана на rebase.

rebaseСубкоманда GIT принимает серию фиксации ( как правило , от вашей точки ветвления на кончик темы ветви topic) и воспроизводить их в другом месте ( как правило , на кончике интеграции отрасли, например master). rebaseСубкоманда производит новые коммиты, что дает возможность перегруппировки фиксаций в форме , которая легче обзор. Это дает новую серию коммитов, аналогичную той, что была topicраньше, но появлялась с корнем в верхней части ветви интеграции. Эта новая ветвь все еще вызывается topicGIT, так что старая ссылка отбрасывается. Я неофициально помечаю topic-0исходное состояние вашей ветки topic-1и так далее по разному рефакторингу.

Вот мое предложение для вашей topicветки:

  1. (Необязательный шаг) Вы в интерактивном режиме перебазировать вашу тему ветвь topicна ее точку ветвления (см --fixupопции commitи -iи --autosquashопцию на rebase), что дает возможность переписать свои коммиты таким образом , что легче обзор. Это приводит к ответвлению topic-1.

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

  3. Пошлите topic-2товарищу по команде, который рассматривает это против наконечника master.

  4. Если topic-2все в порядке, тогда объедините его с мастером.

П р и м е ч а н и е - Ветви - где ветвь ссылается на дерево коммитов - все будут называться GIT одинаково, поэтому в конце процесса только ветвь topic-2имеет имя в GIT.

Плюсы:

  • Нет устаревшего кода в обзоре.
  • Никаких ложных обзоров «иностранных слияний» (явление, которое вы описали в 1-м).
  • Возможность переписывать коммиты чистым способом.

Минусы:

  • Вместо одной отрасли topic-0, есть три ветви артефакты topic-0, topic-1и topic-2которые созданы в фиксации дерева. (Хотя в любое время только один из них имеет имя в GIT.)

В вашем 1-м сценарии «если кто-то слил что-то между« 1 ». и «2.» »означает промежуток времени между созданием точки ветвления и временем, когда вы решили объединиться. В этом сценарии «если кто-то слил что-то между« 1 ». и «2.» относится к промежутку времени между перебазированием и слиянием, которое обычно очень мало. Таким образом, в сценарии, который я предоставляю, вы можете «заблокировать» masterветку на время слияния, не нарушая существенно ваш рабочий процесс, в то время как в первом сценарии это нецелесообразно.

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

Управление артефактами промежуточной ветви представляет сложность, только если вы делитесь ими между репозиториями.

Михаэль Ле Барбье Грюневальд
источник
Там не должно быть topic-0, topic-1и topic-2ветви. Во время второй перезагрузки предыдущая версия не имеет значения. Так что все было бы есть topic@{1}, topic@{2}, topic@{yesterday}, и topic@{3.days.ago}т.д. , чтобы сохранить свою задницу в случае , если вы обнаружили , ввинчиваетесь разрешением конфликтов в перебазировании.
Ян Худек
Три ветви существуют, но не имеют названия (без ссылки). Может быть, я должен подчеркнуть это.
Михаэль Ле Барбье Грюневальд,
Версии существуют и на них указывают записи reflog. Но как ветви есть только один topic. Потому что ветка в git это просто имя.
Ян Худек
Как это спасает меня от "иностранных слияний"? Что если кто-то объединится с мастером после того, как я отправлю тему-2 партнеру по команде, и этот товарищ по команде рассмотрит ее в отношении совета мастера?
Анджей Гис
@JanHudec В любое время, есть только одна ветвь называется topicв GIT, это всегда одна из ветвей (ветвь , как и в фиксации дерева, а не как в GIT ссылке) Я маркирован topic-0, topic-1, topic-2.
Михаэль Ле Барбье Грюневальд