Избегайте повторного разрешения конфликтов в git rebase, включая коммиты слияния - PullRequest
1 голос
/ 05 августа 2020

Попытка переместить историю из одного репо в другое (не типичное root) путем добавления удаленного источника и перенастройки в ветку в локальном репо назначения.

Источник:

A-B-C
 \ /
  E

Требуется в пункте назначения:

F-A'-B'-C'
   \   /
     E'

В документации для git rebase --rebase-merges говорится, что он сохранит топологию и повторно создаст коммиты слияния, но:

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

Теперь я хочу избежать повторного разрешения конфликтов, и я озадачен, зачем это вообще нужно . Содержимое коммита слияния есть, я могу отсоединить HEAD от.

Итак, я попробовал

$ git rebase -i --onto destnewbranch --root --rebase-merges srcbranch
Could not apply C... master # Merge branch 'master'

(detached HEAD|REBASE x/y)
$ git status
interactive rebase in progress; onto F
Last commands done (n commands done):
   pick B
   merge -C C master # Merge branch 'master' 

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Чтобы разрешить конфликты, я беру содержимое C:

$ git reset --hard C

Теперь контент хорош, но история - нет, поэтому:

$ git reset --soft HEAD@{1}

Все, что осталось сделать, это продолжить перебазирование:

$ git commit
$ git rebase --continue

Однако история неверна, так как у меня осталось:

F-A'-B'-C'

Итак, C 'не является фиксацией слияния, хотя в ней есть разрешенные изменения как B, так и E. Слияние коммитов, которые не' t, потому что конфликт успешно перебазирован с неповрежденной топологией. обычный. Если я не сделаю сброс и не разрешу конфликты вручную, фиксация git создаст фиксацию слияния.

git версия 2.26.0. windows .1

1 Ответ

0 голосов
/ 05 августа 2020

Чтобы разрешить конфликт с использованием содержимого существующей фиксации, используйте git restore. Не используйте git reset --hard, который изменяет HEAD.

Однако даже это в большинстве случаев не работает. То, что вы, вероятно, ищете, называется rerere (сокращение от «повторно использовать записанные разрешения»). Включите его в конфигурации Git:

git config rerere.enabled true

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

git config rerere.autoupdate true

Кроме того, вы можете научить rerere прошлым слияниям и разрешенным конфликтам с помощью сценария rerere-train.sh, который часто распространяется с Git (в Ubuntu он доступен по адресу /usr/share/doc/git/contrib/rerere-train.sh). Вызовите его перед перебазированием, чтобы не повторять ранее разрешенные конфликты:

rerere-train.sh destnewbranch..srcbranch
git rebase destnewbranch srcbranch --onto destnewbranch --rebase-merges
...