Как разрешить конфликты слияния в монорепозитории?

Предположим следующую ситуацию:

  • монорепозиторий содержит два артефакта в отдельных папках, скажем, frontend и backend
  • Frontend-разработчики не способны решать конфликты слияния в backend-коде.
  • бэкэнд-разработчики не способны решать конфликты слияния в коде внешнего интерфейса
  • рабочий процесс на основе ветвей функций, при котором разработчики внешнего и внутреннего интерфейса работают параллельно над одной и той же ветвью функций

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

Как лучше всего разрешать конфликты слияния, которые охватывают интерфейсный и внутренний код? Если основной проблемой является вертикальный рабочий процесс, основанный на ветвях функций, как бы вы улучшили эту настройку, придерживаясь первых трех предположений?


person Michael Hoff    schedule 28.08.2020    source источник
comment
Как вы генерируете конфликты, охватывающие два каталога? Если внешние разработчики работают только во внешнем каталоге, их изменения не могут конфликтовать с изменениями во внутреннем каталоге, и наоборот.   -  person jonrsharpe    schedule 28.08.2020
comment
Допустим, у нас есть две ветки функций A и B. Обе происходят из одного и того же коммита в ветке разработки. Обе ветки содержат изменения в бэкенде и интерфейсе. Теперь, после того, как A был объединен с development, вы также хотите объединить B. Для этого вам нужно сначала обновить-слить B. В этот момент может возникнуть конфликт в обоих каталогах.   -  person Michael Hoff    schedule 28.08.2020
comment
Почему бы не объединить разработчиков при работе с этими сценариями? Обратите внимание, что у вас есть еще одна проблема: вы не можете сказать, пока после слияния, действительно ли работает develop+A+B, потому что вы объединяете development+A и development+B - перемещаете B поверх develop+A может помочь, тогда конфликты могут быть разрешены фиксацией за фиксацией. Все это становится проще, когда вы чаще вносите небольшие изменения.   -  person jonrsharpe    schedule 28.08.2020
comment
Я согласен. Тем не менее, объединение разработчиков в пару сейчас сложно, поскольку разработчики работают удаленно и не обязательно в одно и то же время. Мы стараемся, чтобы изменения были ограничены по размеру, но иногда это все же случается.   -  person Michael Hoff    schedule 28.08.2020
comment
Ваша ситуация с ветвями A и B никогда не произойдет, если разработчики внешнего интерфейса будут работать с каталогами внешнего интерфейса, а разработчики внутреннего интерфейса будут работать с каталогами внутреннего интерфейса. Тогда у вас будут ветки, содержащие изменения только в одном наборе этих каталогов. Как возникли ветки A и B? Были ли в одной ветке и фронтенд, и бэкенд разработчики? Если да, то нельзя ли просто привлекать одних и тех же разработчиков при возникновении конфликта?   -  person Lasse V. Karlsen    schedule 30.08.2020
comment
Да, предполагается, что оба разработчика вносят свой вклад в одну и ту же ветку функций. Помимо удаленной работы, проблема с участием обоих разработчиков заключается в том, что разрешение внутренних конфликтов — это задача, для которой не обязательно требуются разработчики внешнего интерфейса, и наоборот. Следовательно, им обоим необходимо совместно разрешать конфликты при слиянии обновлений, решая при этом потенциально независимые проблемы.   -  person Michael Hoff    schedule 30.08.2020
comment
внутренний и внешний код в одном репозитории — источник ваших проблем. нельзя иметь два репозитория типа acme-web и acme-api? Вы решили свою проблему?   -  person JRichardsz    schedule 31.08.2020
comment
Слейте ветки с вашей веткой локально, разрешите любой конфликт и только потом пушите: git checkout my-branch; git merge branch-a   -  person Qumber    schedule 04.09.2020
comment
Я думаю, что это может быть дубликатом.   -  person jthill    schedule 05.09.2020


Ответы (2)


Есть пара типичных подходов к этой проблеме:

  • Часто объединяйте изменения и используйте систему пометки функций, чтобы новые изменения можно было интегрировать, не становясь активными. Это позволяет отдельным разработчикам работать над различными аспектами функции и постепенно объединять ее, поэтому ветвь функции ограничена одним или небольшим числом разработчиков, способных разрешать конфликты по отдельности.
  • Сделайте так, чтобы ветки функций работали как комбинация веток функций отдельных разработчиков, и заставьте каждого разработчика перебазировать свои собственные изменения, разрешая конфликты, а затем повторно интегрировать эти отдельные ветки разработчиков обратно в ветку функций.
  • Попросите разработчиков из каждой области объединиться для работы над разрешением конфликтов.

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

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

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

person bk2204    schedule 29.08.2020
comment
Большое спасибо за Ваш ответ. Не могли бы вы уточнить свой второй подход? Я не понимаю, как вы могли бы избежать проблемы с обновлением-слиянием от разработки до «основной» функциональной ветки. - person Michael Hoff; 29.08.2020
comment
Второй подход делает ветку функций набором веток отдельных функций разработчика, и каждый разработчик перебазирует свои собственные изменения в основную разработку, прежде чем повторно интегрировать их в ветку основной функции, что означает, что они решают свои собственные конфликты во время перебазирования. - person bk2204; 29.08.2020

Вот грубый, технический способ разделить разрешение конфликта слияния на две отдельные части:

  1. из ветки master создайте два фальшивых коммита, один из которых содержит только изменения в backend, а другой - только изменения в frontend

  2. пусть два разработчика объединят каждую ветку в feature

  3. объединить feature в master


  1. разделить изменения на два:
# starting situation :
*--X--*--*--Z <- master      # X is the fork point
    \                        # Z is the tip of branch master
     \
      *--*--*--T <- feature   # T is the tip of branch feature

Выполните следующие команды:

# from master, create a phony branch for backend :
$ git checkout -b backend master
$ git checkout X -- frontend/   # reset the content of 'frontend/' to its state in commit X 
$ git commit

# similarly for fontend :
$ git checkout -b frontend master
$ git checkout X -- backend/
$ git commit

Теперь у вас есть:

*--X--*--*--Z------
    \           \  \
     \           B  F  # B: tip of backend, F: tip of frontend
      \
       *--*--*--T
  1. объединить две части в feature :
$ git checkout feature
# have one developper fix conflicts on :
$ git merge backend
# and a second one on :
$ git merge frontend

Примечание: слияния могут происходить в любом порядке.

Ситуация сейчас такая:

*--X--*--*--Z------
    \           \  \
     \           B  F
      \           \  \
       *--*--*--T--*--M <- feature
  1. теперь вы можете объединить feature в master

Что касается ваших рабочих процессов, если работа над backend и frontend должна выполняться отдельно, вам нужно иметь какое-то правило, чтобы отразить это в ветках, управляемых вашими разработчиками.

@ bk2204 в своем ответе дает несколько указаний по этому поводу: отделите работу над бэкэндом от работы над внешним интерфейсом, объедините как можно скорее.

person LeGEC    schedule 01.09.2020