Последующее слияние после `merge --squash` вызывает конфликты - PullRequest
0 голосов
/ 12 февраля 2020

Обычное слияние:

$ git merge feature01
$ git merge feature02

Все отлично работает.

squa sh слияние:

$ git merge --squash feature01 # OK
$ git merge --squash feature02
Auto-merging src/aaa.js
CONFLICT (content): Merge conflict in src/XXX.js
....

Почему это так? Как заставить merge --squash работать (последующие слияния найдут)?

Ответы [ 3 ]

0 голосов
/ 12 февраля 2020

Ситуация, которую вы описываете, требует, чтобы история выглядела примерно так:

--X--Y             <-- your master
   \
    A--B--C--D     <-- feature01
     \
      R--S--T      <-- feature02

(независимо от того, имеет ли ваш master коммит Y или все еще на X, не имеет значения для следующего.)

Почему это так?

Обратите внимание, что две функции имеют общие коммиты, A в этом примере. Когда вы делаете регулярные слияния, Git знает об этом факте и может справиться с ним, не вызывая конфликтов. В частности, во втором слиянии не снова будет извлекать изменения, сделанные в A.

Но когда вы выполняете сква sh слияние feature01, вы генерируя эту историю:

--X--Y--F1         <-- your master
   \
    A--R--S--T     <-- feature02

Я обрезал feature01 из картинки, потому что она больше не играет роли.

Когда вы делаете слияние feature02 сейчас (squa * 1051) * или обычный не имеет значения) Git пытается применить коммит A снова, потому что у него недостаточно информации, чтобы знать, что он уже слил его. Конфликты возникают, когда один из коммитов B, C, D внес изменения в окрестности изменений, которые A сделал.

Как заставить merge --squash работать (последующее слияние работает нормально)?

Вы не можете. Не используйте merge --squash.

Конечно, вы можете перепрыгнуть через некоторые обручи по истории прививания , чтобы сделать вид, что A действительно было объединено в F1; но это всего лишь обходной путь, лейкопластырь для экстренных случаев, но это слишком утомительно для обычного рабочего процесса. И если вы делаете это, то почему вы не использовали регулярное слияние?

0 голосов
/ 12 февраля 2020

(как упомянуто в своем комментарии @ eftshift0)

Если перед слиянием история ваших двух веток выглядит так:

# featureA and featureB have some common history :
--*--*--x--a <- master
         \
          *--*--y--b <- featureA
                 \
                  *--*--*--c <- featureB
  • Когда работает git merge featureA, git использует существующие коммиты:

    --*--*--x--a---------b' <- master
             \          /
              *--*--y--b <- featureA
                     \
                      *--*--*--c <- featureB
    

    и у него достаточно информации, чтобы знать, что он должен использовать y в качестве базы слияния для featureB,

  • При запуске git merge --squash featureB с другой стороны:

    --*--*--x--a--b' <- master
             \
              *--*--y--b <- featureA
                     \
                      *--*--*--c <- featureB
    

    Создается новый коммит, который больше не связан с веткой featureB, и он попытается повторно применить изменения x..y при объединении featureB.


Вы можете посмотреть историю своих веток:

  • из командной строки : git log --graph featureA featureB master
  • или с использованием gui клиента: git gui, git-kraken, git-extensions, ...
0 голосов
/ 12 февраля 2020

Ну что ж ... я догадываюсь, что есть общая история feature01 и feature02, которая находится за пределами ветви, над которой вы работаете .... когда вы делаете нормальные слияния, git может видеть это, и это часть вычисления слияния ... но если вы слились с Squa sh, то эта общая история исчезнет из виду и может вызвать конфликты ... например, на второй ветви, которую вы сливаете, вы изменить изменение, которое было внесено в первую объединенную ветвь .... если вы попытались объединить его, в git нет исторического контекста, чтобы выяснить, что вы начали с изменения в первой ветви ... так что вы получит конфликт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...