Как мне объединить изменения из сжатого коммита в master, не сталкиваясь с ложными конфликтами?

#git #branch #branching-and-merging

#git #ветка #ветвление и слияние

Вопрос:

Это действительно вопрос git; Azure DevOps имеет значение только потому, что он выполняет сжатие для нас, что приятно.

В Azure DevOps мы с моей командой часто выполняем слияние при завершении запроса на извлечение с «фиксацией сквоша» на скриншоте ниже. Это, по понятным причинам, создает новый коммит в master при слиянии.

Однако этот новый коммит создает ложные конфликты слияния в любой другой существующей ветке, которая пришла из этой ветки. Мне часто хотелось бы создать новую ветку B из ветки A, затем объединить (с помощью коммита squash) ветку A в master, затем объединить master в ветку B, не сталкиваясь со старыми «конфликтами», которые на самом деле не являются конфликтами, потому что они уже были в ветке A, когда я создавал свою ветку B. Есть идеи, как?

Я попытался выполнить перебазирование, но это не решает мою problem…it похоже, мне все еще нужно изучить каждый конфликт и разрешить их.

Очевидно, что Git не знает, что коммит squash связан с журналом ветки B, но обычно я знаю, что коммит есть, и любые конфликты можно разрешить, взяв входящую версию. (Конечно, у меня могут быть несвязанные конфликты из-за изменений в ветке B, но этого следовало ожидать!)

Вот пользовательский интерфейс Azure DevOps, который приводит к этому новому сжатому коммиту, для справки. введите описание изображения здесь

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

1. Как насчет того, чтобы не сжимать?

2. Это создает действительно запутанную историю, которую, я боюсь, быстро станет слишком обременительной для просмотра. Хотя я думал об этом.

3. Короткий ответ: «Вы этого не делаете, по крайней мере, не автоматически», и именно поэтому сжатие может быть плохим. Чтобы решить проблему «сжатие — это плохо», когда вы считаете, что сжатие желательно, рассматривайте любую сжатую ветку как «мертвую»: никогда не делайте с ней ничего другого, просто немедленно удалите ее.

4. В вашем конкретном случае я предполагаю, что у вас есть ветка branch-B , которая добавляет коммиты к этим коммит branch-A . В этом случае, непосредственно перед удалением branch-A , перебазируйте свои branch-B коммиты --onto в основную ветку (в которую были включены другие коммиты), используя branch-A в качестве отсечения, для которого коммиты должны быть скопированы, чтобы скопировать существующие branch-B коммиты поверх сжатого коммита. Это немного сложно, но как только вы получите шаблон, это достаточно легко сделать.

5. Обратите внимание, что сжатие само по себе не вызывает проблемы. Любая перезапись в ветку A (перебазирование или изменение) после отделения ветки B от A вызовет ту же проблему. В общем, вы должны стараться избегать ответвления B от A, когда это возможно, и вместо этого все должны отходить от master. В (надеюсь, редком) случае, когда вам нужно отделить B от A, прежде чем A перейдет в master, тогда я согласен с torek: используйте rebase с опцией —onto, чтобы перебазировать только определенный диапазон фиксации в B.

Ответ №1:

Одной из возможных политик при наличии филиалов, которые зависят друг от друга, является :

  • когда ветвь A будет объединена с основной, вручную перебазируйте все ветви, которые были разветвлены, A на новую master (которая теперь включает A в себя).

Для вашей B ветки это будет означать :

  • определите точку разветвления между B и A (фиксация y на диаграмме ниже)
  • определите коммит, в который «слился» A master (коммит M на диаграмме ниже)

Перебазирование B M будет :

 # a visual of your history :
             <new A> : merge A into master
                  v
*--x--*--*--*--*--M--* <- master
    
     *--*--y--*--*--* <- A
           ^
           | *--*--*--*--* <- B
           |
     <base B> : fork point between A and B

# to rebase 'only the commits of branch B', run :
git rebase --onto <M> <y> B
 

Что вы получаете :

  • масштаб конфликтов будет меньше: вместо сравнения различий, которые произошли с момента x (точка форка A ), git будет проверять только различия, которые произошли с момента y

С чем вам еще нужно справиться :

  • несовместимые изменения в master: если вам пришлось исправлять конфликты при слиянии A , скорее всего, вы снова столкнетесь с некоторыми связанными конфликтами при воспроизведении B поверх M