Si scopre che la risposta è molto più semplice se si sta semplicemente cercando di incollare due repository insieme e far sembrare che fosse sempre così anziché gestire una dipendenza esterna. Devi semplicemente aggiungere telecomandi ai tuoi vecchi repository, unirli al tuo nuovo master, spostare i file e le cartelle in una sottodirectory, eseguire il trasferimento e ripetere per tutti i repository aggiuntivi. I sottomoduli, le fusioni di sottostrutture e le fantasiose rebase hanno lo scopo di risolvere un problema leggermente diverso e non sono adatti a quello che stavo cercando di fare.
Ecco un esempio di script Powershell per incollare due repository insieme:
# 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"
Ovviamente potresti invece unire old_b in old_a (che diventa il nuovo repository combinato) se preferisci farlo - modifica lo script per adattarlo.
Se vuoi portare anche i rami delle caratteristiche in corso, usa questo:
# 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
Questa è l'unica parte non ovvia del processo: non si tratta di un'unione di sottostruttura, ma piuttosto di un argomento alla normale unione ricorsiva che dice a Git che abbiamo rinominato il bersaglio e che aiuta Git a allineare tutto correttamente.
Ho scritto una spiegazione leggermente più dettagliata qui .