Как сгладить два коммитов слияния на высшем уровне, используя git - PullRequest
1 голос
/ 14 февраля 2020

Я недавно столкнулся с git сценарием, с которым я не знаю, как справиться. Сначала давайте установим сцену.

Идеальный рабочий процесс

Предположим, вы поддерживаете разветвление большого проекта с открытым исходным кодом, в котором апстрим разрабатывает с использованием запросов извлечения (PR). Поскольку upstream выполняет PR, их git история имеет множество коммитов слияния.

Периодически вам придется синхронизировать c ваше дерево с upstream. Обычно это выглядит так:

  • git checkout -b sync
  • git pull upstream master
  • Исправить конфликты слияния до git add файлов конфликтов, затем git commit .

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

Проблематично c Сценарий

  • git checkout -b sync
  • git pull upstream master
  • Вы исправляете конфликты слияния, git add и git commit им.
  • Вы запускаете свой CI и тесты не пройдены, потому что апстрим что-то сломал.
  • Через два дня апстрим решает проблему.
  • git pull upstream master
  • Снова исправьте конфликты слияния.

В этот момент ваша ветвь sync содержит две созданные вами коммиты слияния. Каждый отдельный коммит слияния содержит различные коммиты и слияния восходящего потока.

Вы можете запустить CI и выполнить слияние сейчас, но этого не следует делать, поскольку ваш первый коммит слияния будет мешать будущему git bisects. В идеале у вас должен быть один коммит слияния, который является суммой двух коммитов слияния в последовательности.

Как можно объединить эти два коммита слияния в один, но сохраняя git историю восходящего потока?

Примечания

git rebase --preserve-merges - это а) устарело, и б) все или ничего. Вы не можете выборочно сохранить все слияния вверх по течению, но сгладьте ваши.

Я пытался использовать git rebase --rebase-merges -i origin/master и пометить второе слияние f для исправления, но это не дает желаемого эффекта. У меня есть коммиты слияния для файлов, которых я никогда не трогал.

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

1 Ответ

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

Если я правильно понимаю, вам нужен один коммит слияния: вышестоящее дерево, включая последние исправления, слилось с вашей веткой sync. Итак, вот что вы должны сделать: сбросьте вашу ветку syn c на фиксацию до первоначального слияния, а затем снова выполните слияние.

Если вы внесли дополнительные изменения в ветку syn c после исходное слияние, но до того, как вышестоящие исправления стали доступны, вы можете переназначить эти коммиты на коммит до первоначального слияния:

git checkout -b sync
git rebase --onto ${PREMERGECOMMIT} ${MERGECOMMIT}
git pull upstream master
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...