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

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

Теперь, когда мы пытаемся перейти от исправления ошибок ветки поддержки к ветке dev-релиза, появляется много конфликтов, связанных с разными командами/областями разработки. Поскольку у нас нет одного человека, отвечающего за серверную и мобильную части, очень сложно разрешать конфликты одному человеку.

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

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


person monitor    schedule 15.12.2017    source источник


Ответы (2)


git checkout -b server-team-merge dev-release-branch
git merge support-team-fixes
# fix the conflicts you can fix here
git commit -m "server-team partial merge of $(git describe support-team-fixes)"

и каждая другая команда делает то же самое. Затем объедините ветки частичного слияния - если результаты действительно не пересекаются, вы можете сделать их все сразу, это будет тривиальная операция,

git checkout dev-release-branch
git merge {server,mobile,ci,automation}-team-merge

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

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

person jthill    schedule 15.12.2017
comment
Извините, не совсем понятно, что мне делать с исправлениями вне моей области после слияния - просто оставить их висеть в конфликтном состоянии и не коммитить? - person monitor; 15.12.2017
comment
также можем ли мы исключить из коммита все автоматически слитые файлы, если они не принадлежат нашей области? Я хочу, чтобы ветка сервера содержала только исправления, связанные с сервером. - person monitor; 15.12.2017
comment
Вы, безусловно, можете перезаписать все локальные изменения в файлах вне области действия перед фиксацией результатов слияния, xargs -d\\n git checkout MERGE_HEAD -- <out-of-scope-files чтобы просто принять входящий контент как есть (если не может быть конфликтов, вы можете использовать --no-commit при слиянии, чтобы создать возможность для исправлений, таких как это). Может быть, сгенерировать журнал таких изменений, разметив git ls-files вывод, и убедиться, что кто-то поручился за каждое из них в финальном коммите. - person jthill; 15.12.2017
comment
Но неконфликтующие изменения должны автоматически объединяться одинаково при каждом слиянии, поэтому не имеет значения, откуда финальное слияние получает свое содержимое, это буквально все та же разница. Подумав об этом, я не вижу необходимости в перезагрузке. Для разрешения конфликтов, предположительно, у вас есть какой-то способ определить, кто, внося изменения в какое слияние, имеет право разрешать каждый конфликт, поэтому просто возьмите версию этой ветки, чтобы все, что было сделано в других ветвях, не имело никакого значения. - person jthill; 15.12.2017

Ну, вы можете попробовать что-то вроде этого:

  1. Оформить заказ dev-release-branch и начать первое слияние с support-branch.
  2. Разрешить как можно больше конфликтов (одним человеком). Файлы и каталоги, которые не удалось объединить этому парню, должны быть возвращены в состояние dev-release-branch.
  3. Зафиксируйте полученное состояние как a-half-of-a-merge, сохраните его как (временный локальный) тег.
  4. Вернуть dev-release-branch в состояние до слияния
  5. Выполните еще одно слияние с support-branch другим парнем, который может объединить другие части исходного дерева. Опять же, отмените изменения, которые не учитываются, как на шаге 2.
  6. Если есть изменения, которые нужно объединить, повторите шаги 3-5 (конечно, выберите другое имя тега).

Когда все конфликты с последнего «домена» разрешены, но коммит слияния еще не создан, начнем объединять изменения из разных «полутэгов».

  1. Добавьте текущий набор изменений в файл index.
  2. cherry-pick отличается от первого half-tag. Вам нужно будет указать родителя слияния с переключателем -m (вероятно, -m 1) и --no-commit
  3. разрешите любой конфликт, который возникнет на этом этапе. Надеюсь, список будет коротким или очевидным
  4. добавить изменения в индекс
  5. повторите шаги 2-4 для всех half-tags
  6. наконец совершить Великое слияние.
  7. Теперь все полутеги можно смело удалять.

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

person user3159253    schedule 15.12.2017
comment
У нас есть что-то похожее, но у меня сложилось впечатление, что мы что-то упускаем, и должен быть более простой способ сделать это в git. - person monitor; 15.12.2017
comment
Что ж, есть способ попроще — посмотрите ответ @jthill. Но его подход оставляет беспорядок из промежуточных слияний в графе истории, и, что может быть важнее, он эффективно взрывает механические умы CI-роботов. - person user3159253; 16.12.2017