Как обеспечить 1 фиксацию слияния для стратегии запроса на вытягивание BitBucket No-FF в ветке с ограниченным доступом?

Я бы хотел, чтобы базовая ветвь всегда не имела эффекта перемотки вперед (всегда создает фиксацию слияния). Основываясь на следующих настройках Bitbucket, используемых моей командой, кажется, что иногда необходимо создать 2 коммита слияния для разрешения конфликта.

Настройки ветки сервера Bitbucket

  • Изменения без запроса на вытягивание — предотвращает отправку изменений непосредственно в указанную(ые) ветку(и); изменения разрешены только с запросом на вытягивание. Разрешения ветки

  • Коммит слияния (--no-ff) Всегда создавайте новый коммит слияния и обновляйте целевую ветвь до него, даже если исходная ветвь уже соответствует целевой ветке. Стратегия слияния по умолчанию

Так как базовая ветвь может быть изменена только с помощью пулл-реквестов, и она всегда создает фиксацию слияния при PR-слиянии, поэтому кажется, что пулл-реквесты, требующие ручного разрешения конфликтов, должны будут иметь 2 коммита.

Пример проблемного сценария:

Вот сценарий: базовая ветвь объединяется с функциональной ветвью, чтобы вручную разрешить конфликт, в этом случае разрешенные вручную конфликты приводят к фиксации слияния. Затем, после нажатия фиксации конфликта-слияния, PR будет обновлен и готов к слиянию, а после слияния с базой он создаст еще одну фиксацию слияния (из-за опции no-ff). Технически нужен был только 1 из этих 2 коммитов. Когда это делается непосредственно в git (без запроса на извлечение и без заблокированной ветки), этого можно было бы добиться с помощью no-ff путем слияния непосредственно с базовой веткой.

Есть ли что-то, что мне здесь не хватает? Есть ли способ добиться ровно 1 фиксации слияния с использованием ограничений запросов на вытягивание Bitbucket Server?


person progner    schedule 10.07.2018    source источник


Ответы (1)


Это ожидаемый результат, если вы установили изменения слияния в базовой ветке через PR и со стратегией слияния no-ff.

Предположим, что базовой веткой является ветка master, а запрос на включение предназначен для слияния ветки feature в ветку master, а история коммитов приведена ниже:

…---A---B---C---D     master
             \
              E---F  feature

Если вы разрешите конфликт слияния путем слияния ветки master с веткой feature со стратегией слияния по умолчанию и после завершения PR, то история коммитов будет такой, как показано ниже (коммит G — это первый объединенный коммит, а коммит H — второй объединенный коммит):

…---A---B---C-------D---H     master
             \       \ /
              E---F---G  feature

Чтобы история коммитов выглядела более четко, вы можете изменить способ разрешения конфликта слияния с помощью git cherry-pick или стратегии слияния со сглаживанием.

  • Если разрешить конфликт функции слияния с основной ветвью слияния с git cherry-pick:

    git checkout feature
    git cherry-pick D
    # resolve all conflicts
    git add .
    git cherry-pick --continue
    git push origin feature
    

    После завершения PR история коммитов будет такой:

    …---A---B---C---D-------M     master
                 \         /
                  E---F---D'  feature
    
  • Если разрешить конфликт функции слияния в основной ветке слияния с слиянием сквоша:

    git checkout feature
    git merge master --squash
    # resolve all merge conflicts
    git add .
    git commit
    git push origin feature
    

    После завершения PR история коммитов будет такой:

    …---A---B---C---D-------M2     master
                 \         /
                  E---F---M1  feature
    
person Marina Liu    schedule 11.07.2018
comment
Спасибо за ваше объяснение. Возможно, я делаю что-то не так, я попробовал оба примера, и для слияния с мастером по-прежнему требуется разрешение конфликтов. В этой серии команд последняя фиксация сквоша на самом деле ничего не совершит: git init; echo "A" > "f"; git add f; git commit -m "A"; echo "B" > f; git add f; git commit -m "B"; echo "C" > f; git add f; git commit -m "C"; git checkout -b feature; echo "E" > f; git add f; git commit -m "E"; git checkout master echo "D" > f; git add f; git commit -m "D"; git checkout feature; echo "F" > f; git add f; git commit -m "F"; git merge master --squash - person progner; 12.07.2018
comment
Проверка статуса git после того, как он не слился с веткой функций. В функции ветки ничего не фиксируется, рабочее дерево чистое. Интересно, потому что содержимое F осталось прежним после разрешения конфликтов, git был достаточно умен, чтобы не сливаться с чем-то, что было бы снова разрешено до слияния. - person progner; 12.07.2018
comment
Я попробовал еще раз, на этот раз обновленный, чтобы не полностью заменить конфликтующий текст. На этот раз он создал сквош-коммит с этими командами, но все равно должен был снова разрешать конфликты на мастере после. git init; echo "A" > "f"; git add f; git commit -m "A"; echo "B" > f; git add f; git commit -m "B"; echo "C" > f; git add f; git commit -m "C"; git checkout -b feature; echo "E" > f; git add f; git commit -m "E"; git checkout master; echo "E_keep_D" > f; git add f; git commit -m "D"; git checkout feature; echo "EF" > f; git add f; git commit -m "F"; git merge master --squash - person progner; 12.07.2018
comment
@progner Да, слияние сквоша должно иметь конфликты слияния. Вы можете думать об обратном: при создании PR для слияния ветки feature с веткой master возникают конфликты слияния для файла f (содержимое файла f на ветке master изменяется с содержимым E_keep_D, а содержимое EF на ветке feature ). Цель слияния master в ветке feature состоит в том, чтобы изменить файл f в ветке feature так же, как содержимое в master, чтобы PR мог слиться без конфликтов. - person Marina Liu; 12.07.2018
comment
@progner Ситуация вряд ли произойдет после того, как вы защитите master ветку. Это означает, что никакие изменения не могут быть отправлены в ветку master сразу после этого. Один и тот же файл будет в основном изменен только с одной стороны (ветвь функции). - person Marina Liu; 12.07.2018
comment
Достаточно справедливо, но если сначала сливается другая ветвь функций, она возвращается к той же ситуации. Из моего тестирования видно, что каждый раз, когда конфликты разрешаются в ветке функций путем внесения основных изменений, их обязательно нужно будет разрешать снова после объединения с основным. Поскольку сервер Bitbucket не поддерживает слияние, кажется, что этого невозможно избежать, пока Bitbucket не добавит функцию разрешения конфликтов. - person progner; 12.07.2018
comment
@progner Для большинства сторонних мест для размещения удаленного репозитория git, таких как bitbucket, github и т. Д., Требуется разрешить конфликт слияния вручную. И в вашем примере файл f действительно будет идти в оригинальную версию, т.к. есть только один файл для проверки. И вы можете перебазировать функцию в последнюю основную ветку после того, как другие ветки функций объединились в основную ветку. Команды как: git checkout feature, git pull origin master --rebase. - person Marina Liu; 13.07.2018
comment
@progner Можете ли вы разрешить конфликт слияния с помощью слияния или выбора вишни сейчас? - person Marina Liu; 16.07.2018
comment
Я предпочитаю не перебазировать (мне нравятся отдельные коммиты + коммит слияния). Я думаю, что ваше первоначальное утверждение отвечает на мой вопрос: This is expect result if you have set merge changes into the base branch via PR and with no-ff merge strategy. В идеале произойдет только 1 фиксация слияния, но PR — это автоматизированная операция, которая не может разрешать конфликты. Спасибо за вашу помощь! - person progner; 19.07.2018