Разрешить слияние несвязанных историй в git rebase

Если вы хотите переустановить ведение слияния веток, вы передаете флаг --preserve-merges. Когда вы объединяете несвязанную историю в git, вам нужно передать флаг --allow-unrelated-histories.

Если вы выполняете git rebase --preserve-merges, когда существующее слияние происходит из несвязанной истории, оно терпит неудачу:

фатальный: отказ от объединения несвязанных историй

Если вы попробуете git rebase --preserve-merges --allow-unrelated-histories, это не с:

error: неизвестная опция 'allow-unrelated-historyories

Есть ли другой способ сказать rebase, чтобы разрешить слияние?


Изменить: здесь минимальное воспроизведение: https://github.com/vossad01/rebase-unrelated-merge-reproduction

Чтобы воспроизвести чек master, выполните:

git rebase --preserve-merges --onto origin/a-prime HEAD~2

Ответ 1

Метод грубой силы - принудительно использовать общий корень - поскольку вы пытаетесь переустановить корни, без истории содержимого, сделайте незанятое завершение фиксации и сообщите git, что родитель истории, которую вы объединяете

git rev-list --all --max-parents=0 \
| awk '{print $0,empty}' empty=`:|git mktree|xargs git commit-tree` \
> .git/info/grafts
git rebase here
rm .git/info/grafts

Ответ 2

Когда git rebase выходит из строя при слиянии, он не прерывает rebase, поэтому у вас есть возможность вручную вмешаться.

Если вы готовы разрешить это вручную, вы можете завершить слияние следующим образом:

git merge --allow-unrelated ORIGINAL_BRANCH_THAT_WAS_MERGED --no-commit
git commit -C ORIGINAL_MERGE_COMMIT
git rebase --continue

В идеале для Git был бы способ справиться с этим без ручного вмешательства.

Ответ 3

Чтобы воспроизвести мастер проверки, выполните:

git rebase --preserve-merges --onto origin/a-prime HEAD~2 -i

Документы git -rebase говорят, что они не объединяют -i и --preserve-merges.

[- preserve-merges] использует внутреннее средство -интерактивный механизм, но явно не рекомендуется использовать его с опцией -интерактивный вариант, если вы не знаете, что делаете (см. ниже).

Но даже без -i он все равно не работает с fatal: refusing to merge unrelated histories.

Часть проблемы HEAD~2 является прямым предком origin/a-prime. Ваше тестовое репо выглядит следующим образом:

1 [master]
|
2
|\
| |  3 [origin/a-prime]
| |  |
| 4 / [origin/b]
|  /
| /
|/
5 [origin/a]

HEAD~2 of master равно 5. origin/a-prime равно 3. Ваша команда эквивалентна:

git rebase -p --onto 3 5

5 является прямым предком 3, поэтому команда не имеет большого смысла. Если это вообще работает, это будет делать что-то странное.


случаи, с которыми я сталкивался несколько раз недавно, заключались в перемещении проектной документации из GitHub Wiki на страницы GitHub (когда веб-сайт уже существует).

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

Но когда у вас есть две действительно расходящиеся истории, лучше оставить их расходящимися историями. Слияние их говорит правильную историю: веб-сайт и документы были разработаны отдельно, но затем объединяются в одну единицу.

1 - 3 - 5
         \
  2 - 4 - 6 - 7 - 8 [master]

Вы можете смотреть на них отдельно в топологическом порядке (8, 7, 6, 5, 3, 1, 4, 2), используя git log --topo-order, или вы можете смотреть на них чередующимися в порядке даты (8, 7, 6, 5, 4, 3, 2, 1), git log по умолчанию. Такой визуализатор истории, как gitk или GitX, будет показывать оба порядка одновременно.

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

1 - 3 - 5 - 2 - 4 - 6 - 7 - 8 [master]

Это теряет жизненно важную информацию и заставляет задуматься, почему определенные изменения стали более трудными в будущем.

Сделайте слияние, это правильная вещь.