Acontece que a resposta é muito mais simples se você estiver simplesmente tentando colar dois repositórios e parecer que era assim o tempo todo, em vez de gerenciar uma dependência externa. Você só precisa adicionar controles remotos aos seus repositórios antigos, mesclá-los ao seu novo mestre, mover os arquivos e pastas para um subdiretório, confirmar a movimentação e repetir para todos os repositórios adicionais. Sub-módulos, mesclagens de sub-árvores e rebotes sofisticados destinam-se a resolver um problema ligeiramente diferente e não são adequados para o que eu estava tentando fazer.
Aqui está um exemplo de script do Powershell para colar dois repositórios:
# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init
# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
git commit --allow-empty -m "Initial dummy commit"
# Add a remote for and fetch the old repo
git remote add -f old_a <OldA repo URL>
# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories
# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | %{git mv $_.Name old_a}
# Commit the move
git commit -m "Move old_a files into subdir"
# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | %{git mv $_.Name old_b}
git commit -m "Move old_b files into subdir"
Obviamente, você pode mesclar old_b em old_a (que se torna o novo repositório combinado) se preferir fazer isso - modifique o script para se adequar.
Se você deseja trazer ramificações de recursos em andamento também, use o seguinte:
# Bring over a feature branch from one of the old repos
git checkout -b feature-in-progress
git merge -s recursive -Xsubtree=old_a old_a/feature-in-progress
Essa é a única parte não óbvia do processo - não é uma mesclagem de subárvore, mas um argumento para a mesclagem recursiva normal que informa ao Git que renomeamos o alvo e ajuda o Git a alinhar tudo corretamente.
Eu escrevi uma explicação um pouco mais detalhada aqui .