Объединение несвязанных репозиториев git, сохраняющих историю/ветки

у нас есть 3 отдельных репозитория git (каждый с некоторыми ветвями), которые мы хотели бы объединить в один, сохраняя полную историю и возможность доступа к ветвям, например:

так это то, что у нас есть. 3 соглашения:

/A/.git
/B/.git
/C/.git

и мы хотели бы иметь одно супер-репо с 3 подкаталогами:

super/.git
super/A
super/B
super/C

и скажем при переключении на функцию branch1 (которая первоначально была в репо B, введенная в то время, когда репо C еще не существовало), мы ожидаем, что результатом будет:

super/.git
super/A
super/B

мы прочитали Объединение нескольких хранилищ git, но возникли проблемы с использованием git -stitch-repo, которые в основном работали как рекламируемые только в том, что довольно большое количество в супер-репо отсутствовали коммиты (без сообщений об ошибках, указывающих на проблему).

любая идея, что мы можем делать неправильно здесь?

ИЗМЕНИТЬ мы знаем о подмодулях и слиянии поддеревьев, но оба они не являются опцией. предполагается, что это одноразовая операция. нам нужно, чтобы репозиции объединялись раз и навсегда.

ИЗМЕНИТЬ вероятно, более простой способ поставить в основном тот же вопрос: скажем, у нас есть одно репо с 3 совершенно несвязанными ветвями. мы можем объединить их без конфликта с одной ветвью (поскольку у них нет файлов). теперь, когда мы смотрим на историю, мы видим 3 несвязанные ветки коммитов и одну точку, где они собрались вместе. но то, что мы хотели бы видеть, - это одна ветвь, состоящая из чередующихся (по дате/времени) совершения всех трех ветвей.

Ответ 1

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

Приведите все истории в одно репо. Используйте ветвь filter-branch для reset каталогов, в которых находится каждая история репозиториев. Нет необходимости сшивать. Вы можете просто объединиться в любой точке, когда вы выполняете ветвь фильтра.

По существу repoA/master, repoB/master и repoC/master будут существовать в новом репо, который вы делаете (хотя вы можете только начать с одного из них). После того, как вы примените ветвь фильтра, каждое дерево в каждой фиксации будет иметь новый root node, который будет каталогом (A для ветвей repoA, B для ветвей repoB и т.д.).

ИЛИ

git checkout -b newbranch --root
git log --all --format=%ad%H | sort | cut -c10- | xargs -n 1 git cherry-pick

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

надеюсь, что это поможет.

Ответ 2

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

Ответ 3

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

Просто создайте новый каталог и git запустите его как свое "супер" репо. Затем добавьте свои репозитории A, B и C, используя команды, указанные в приведенной выше ссылке.