#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