Resulta que la respuesta es mucho más simple si simplemente está tratando de pegar dos repositorios y hacer que parezca que fue así todo el tiempo en lugar de administrar una dependencia externa. Simplemente necesita agregar controles remotos a sus repositorios antiguos, fusionarlos con su nuevo maestro, mover los archivos y carpetas a un subdirectorio, confirmar el movimiento y repetir para todos los repositorios adicionales. Los submódulos, las fusiones de subárboles y las refinadas modificaciones tienen la intención de resolver un problema ligeramente diferente y no son adecuados para lo que estaba tratando de hacer.
Aquí hay un script de ejemplo de Powershell para pegar dos repositorios:
# 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, podría fusionar old_b en old_a (que se convierte en el nuevo repositorio combinado) si prefiere hacerlo: modifique el script para adaptarlo.
Si desea traer también ramas de características en progreso, use esto:
# 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
Esa es la única parte no obvia del proceso: no es una fusión de subárbol, sino un argumento de la fusión recursiva normal que le dice a Git que cambiamos el nombre del objetivo y que ayuda a Git a alinear todo correctamente.
Escribí una explicación un poco más detallada aquí .