Как разработать brach, когда он объединен с другими развивающимися ветвями

#git #git-merge #git-workflow

Вопрос:

Представьте себе две ветви: 124 (моя) и 158, обе находятся в стадии разработки.

  1. Я объединяю commitA 158 в 124.
  2. В 158 — commitA файлы переименованы, содержимое изменилось после переименования, теперь это 158- commitB .
  3. 158 поднял пиар, который был объединен в мастер-класс. После этого удаленный филиал 158 был закрыт.
  4. Я не знал о № 2 и № 3, поэтому не синхронизировал 124.
  5. Я начал открывать PR для 124 и обнаружил, что файлы, которые я объединил из 158, commitA теперь отображаются как новые файлы в PR/слиянии 124.
  6. Я проверил PR 158, нашел изменения, изменил их и на 124.

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

Комментарии:

1. Следуя рекомендациям по ветвлению git, как указано здесь: nvie.com/posts/a-successful-git-branching-model

2. Пожалуйста, обновите свой вопрос, уточнив #1 (было ли это истинное слияние, выбор вишни или перебазирование?) и #2 (было ли 158- commitB переписывание истории 158 — commitA ?)

3. @Inigo В вопросе уже указано, что ветвь 158 была «объединена в сквош» для освоения, что эффективно отвечает на оба ваших вопроса: сквош-это тип переписывания истории.

4. Нет, это совсем не ясно, и я думаю, что вы не понимаете моих вопросов. Задача задающего вопрос состоит в том, чтобы найти время, чтобы сделать вопрос очень ясным и недвусмысленным, и ответить на уточняющие вопросы, потому что многие пользователи SO часто используют неправильные термины, а люди тратят время на ответы с неправильными предположениями. Мой первый вопрос был не о пиаре, а о вашем «слиянии» commitA из 158. Я хочу убедиться, что это было слияние, а не выбор вишни. Это означало бы, среди прочего, что commitA это первый коммит после точки развилки ваших двух ветвей.

5. Точно так же мой второй вопрос касался НЕ пиара, а характера commitB . Было ли это обязательство сверху commitA ? Или была commitA изменена и заменена на commitB ? Это важно, потому что они приводят к различным историям фиксаций и изменяют возможности поиска решения, не основанного на ручном управлении. Потому что, как указывает @IMSoP, переписывать историю-это плохо, когда несколько человек работают над одним и тем же кодом. Но в зависимости от того, как была переписана история, могут быть или не быть более простые способы выкопать себя из ямы. Смотрите мой комментарий к ответу @IMSoP.

Ответ №1:

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

В вашем примере ранняя работа над ветвью 158 была передана ветви 124. Однако затем вы использовали опцию слияния «сквош», которая переписывает историю, создавая одну фиксацию из нескольких. Это означает, что git никак не может знать, что изменения в 124 связаны с новой версией 158, поэтому, когда вы объедините 124 в master, он попытается объединить их снова.

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

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

Если два разработчика правильно общаются, автор 158 может безопасно переписать историю своей ветви (с перебазированием, объединением сквоша и т. Д.) — автору 124 просто нужно знать об этом и переписать свою историю, чтобы соответствовать, используя git rebase . Хотя обычно этого легче избежать, где это возможно.

Комментарии:

1. Полностью согласен. Но есть и второй фактор, который я пытаюсь прояснить в операции. Помимо слияния сквоша в master, похоже, что даже первоначально общая фиксация, 158 — commitA , была изменена (т. Е. переписана история) до слияния в master, что означает, что даже прямое слияние не помогло бы.

2. @Inigo Я добавил краткое примечание, что для пропуска коммитов оба слияния должны быть полными коммитами слияния.

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

4. @IMSoP Спасибо за этот отличный ответ , я думал о squash-merge том, чтобы удалить историю и вызвать эту ситуацию, но я не проверял это, пока не поймал это на работе. Кроме того, я думаю, что если бы 158 не был закрыт после слияния с master , это могло бы оставить для меня последнюю фиксацию(124) для синхронизации, был бы это альтернативный способ, все равно это не «автоматически». К вашему сведению, наш проект заставляет разработчиков использовать сквош-слияние при PR

5. @Caper Как я уже сказал, есть проблема с коммуникациями, если вы узнали о дополнительных изменениях только после того, как они были объединены; git не может это исправить. Объединение дополнительных изменений могло бы помочь; но в зависимости от связанных изменений и того, как они были внесены, это может привести к запутанным конфликтам при объединении в master. В конечном счете, политика использования слияний сквоша, вероятно, предполагает, что все ветви независимы; это явно отбрасывает любую информацию об отношениях между ними. Если вы не можете изменить эту политику, вам нужно будет быть еще более активным в общении.