Если ваша история довольно линейна (т.е. просто master
в каждом из А и В), это не будет слишком плохо. Если есть много филиалов, с которыми можно бороться, он будет более активным (см. Обновление ниже), но все же это обеспечило бы отправную точку:
Сначала создайте репозиторий C.
git clone /url/for/repo/A C
cd C
Теперь извлечь все объекты из B
git remote add B /url/for/repo/B
git fetch B
Теперь мы должны иметь обе истории в новом C репо.Rebase B репо совершает на историю
git rebase --onto master --root B/master
Теперь вам необходимо обновить master
реф и, возможно, очистить немного
git branch -f master
git remote remove B
Теперь А в списке, как ваш origin
удаленный; вы, вероятно, либо хотите нажать на нее, либо удалить ее как источник, в зависимости от того, собираетесь ли вы использовать A для того, чтобы содержать все в будущем.
- UPDATE: Хорошо, вот немного больше информации в случае, если ваша история не является линейным, так как он, вероятно, никогда это ... Сначала давайте сосредоточимся на топологии, то слово или два на рефов ...
Топология-накрест, на самом деле есть три общих сценария:
1) Филиалы и сливается в B
Так давайте предположим, что у вас есть один кончик ветви в B (если нет, прочитайте это, а затем просмотрите сценарий 2), который прослеживается до одного корня, который вы можете перенести на один кончик ветки в A (если не увидеть сценарий 3 ниже, вернитесь к этому) ,
A1 ---- A2 ---- A3 <--- (master)
\ /
A4 -- A5
---------------------------
B1 ---- B2 ---- B3 <--- (master)
\ /
B4 -- B5
Там, возможно, были филиалы в А, но в конечном счете они были объединены назад, и вы не должны беспокоиться о них. Там также могут быть ветви в B, и хотя они объединены обратно, они могут вызвать проблемы, если rebase попытается сделать их линейными.
Начните с создания C и импорта обеих историй, как мы это делали выше. (В конце я предлагаю небольшое изменение этой процедуры, имея отношение к refs ... но вернемся к этому.)
Теперь у вас есть два варианта. Простейшим далеко должен использовать filter-branch
(но это может занять много времени). Найдите значение хэш-функции фиксации, на которую вы будете прививкой (помечено A3 выше) и запустить
git filter-branch --parent-filter 'sed "s/^\$/-p xxxxxxxxxx/"' B/master
(где XXXXXXXXXX является хэш-значение).
Это предполагает, что у вас есть sed; он доступен в среде git bash в Windows или почти в любой системе * nix. Если нет, вы можете найти эквивалентный фильтр. (Все, что он делает, говорит: «Если ввод пустой строки, напишите« -p », за которым следует хеш, на который я пересаживаю, иначе передайте вход через мой вывод».)
Если для некоторых причина, по которой вы не можете этого сделать, или если это похоже на проблему с производительностью, тогда вы можете попробовать план b: дать --preserve-merges
вариант rebase
... и это будет делать то, что вы хотите много времени. Но есть серьезные оговорки.
В принципе, если слияние внесло изменения вручную - либо потому, что руководство разрешение конфликтов было необходимо, или потому, что слияние было сделано с --no-commit
и ручными изменениями были введены таким образом - то слияние не будет воспроизводиться должным образом перебазироваться даже с этой опцией.
В случае конфликта, перестановка должна прекратиться и позволить вам повторно применять ручные разрешения (что вы, возможно, сможете сделать с проверкой пути (checkout ... -- .
) первоначального слияния, но в случае, если кто-то использовал --no-commit
перебазироваться даже не поймет, ничего плохого.
Если вы знаете, что это будет проблемой, но может определить один или два проблема сливает, то один из вариантов является перебазирования каждого из родителей проблемного Merge, а затем переделывать слить вручную, затем продолжить с этой точки дальше.
Если вы не знаете, если/где p будут возникать ошибки, вы можете попробовать rebase, а затем выполнить проверку для сравнения коммитов. Перед тем, как перебазироваться
git checkout master
git tag old-B-master
Тогда попробуйте Rebase
git rebase --preserve-branches --onto master --root B/master
git tag new-B-master
Затем сделать то, что уровень проверки кажется безопасным для вас. (Очевидно, что дифф old-B-master
против new-B-master
, как минимум. Когда я сделал что-то вроде этого, я написал сценарий рекурсивно траверс коммита древностей сравнения фиксации по фиксации. Paranoid? Возможно.)
Если только это идет очень, очень гладко, вам, вероятно, лучше отказаться от подхода filter-branch
.
2) Несколько советов филиалов в B
A1 ---- A2 ---- A3 <--- (master)
\ /
A4 -- A5
---------------------------
B1 ---- B2 <--- (master)
\
B4 -- B5 <--- (branch1)
Может быть, ваш B репо не полностью слиты. Это может или не может усложнить ситуацию. Если вы используете filter-branch
, он может работать на многих ссылках одновременно. Вы, вероятно, не можете просто сказать --all
(потому что это может уловить ссылки, которые уже находятся в дереве A
, и, скорее всего, операция закончится неудачей), но вы можете перечислить подсказки ветки из дерева B
.
git filter-branch --parent-filter 'sed "s/^\$/-p xxxxxxxxxx/"' B/master B/branch1
Если вы пытаетесь использовать перебазироваться (или если вы просто хотите работать с одним наконечником исх), вы можете создать временный осьминога слияния.
git checkout B/master
git checkout -b b-entry-point
git merge -s ours B/branch1 B/branch2 ...
В результате слияние происходит временно. (Вы можете удалить ветвь b-entry-point после трансплантата.) Она просто предоставляет единственную «точку входа» в дерево фиксации B
.
3) Несколько советов филиалов в A
A --- Am <-- (master)
\
Ab1 <-- (branch1)
---------------------------------------
B1 ---- B2 <-- (master)
B3 ---- B4 <-- (branch1)
Так что, если не был полностью слиты в первую очередь? Когда вы создали репо B, вы только создать один новый фиксатор B === Am
? Я так думаю, потому что вам пришлось бы сделать что-то странное, как несколько деревьев истории, чтобы включить представление Ab1
, и у вас возникла бы небольшая головная боль, если вы захотите повторно объединить ...
Если у вас есть несколько деревьев для трансплантации, то я думаю, вам просто придется обрабатывать каждый отдельно. Не так много, чтобы это улучшить.
Если у вас есть несколько привитых очков, но они с тех пор были вновь объединены в M
, то вам, вероятно, придется прививать каждого из родителей M
«s индивидуально, а затем воссоздать слияние как M'
, а затем продолжить прививкой детей от M
до M'
.
Хорошо, но как насчет ссылок?
Теперь вышесказанное в порядке, но у вас могут быть ссылки (в A и/или в B), о которых вы заботитесь, кроме как только ветка master
.
Это одна из тех вещей, которые лучше всего обрабатываются filter-branch
; на самом деле, если я правильно напомню, rebase
не будет переписывать какой-либо референт, за исключением того, что его ветвление отбрасывается (а не даже если это удаленная ветка ref).
Особенно при использовании filter-branch
, вы можете обнаружить, что удобно для создания C клонирования B и импорт удаленных рефов формы А (а не наоборот, как было показано выше), так что вы можете иметь filter-branch
переписать локальные реф для вас ,
Несмотря на это, вы можете найти комбинацию удаленных ссылок, которые необходимо переместить. Команды ветви и тегов с параметром -f
могут использоваться по мере необходимости, выравнивая локальные ссылки на любой удаленный реф, наиболее подходящий для вашего конечного состояния.
В настоящее время я использую ваше решение, которое является лучшим на данный момент и которое я пробовал до использования подхода «вишневый выбор», но, как вы сказали, если есть больше филиалов, это будет более активно и от того, что я видя во время перезагрузки, часто встречаются конфликты слияния. Они очевидны из-за того, что rebase пытается линеаризовать (rebase) историю фиксации B при объединении ее поверх A. Если я ошибаюсь, скажите мне. Если это так, можно ли предотвратить процесс линеаризации? – Ivan
Я добавлю несколько заметок о работе с несколькими ветвями; из первоначального вопроса я надеялся, что у вас просто была линейная история и ленился. –
Несмотря на то, что обновление, которое я предоставил, может помочь, вы можете немного удержаться на втором обновлении ... Я думаю, что в некоторых случаях эти инструкции сделают беспорядок ref. –