I need to merge two Git repositories into a brand new, third repository. I’ve found many descriptions of how to do this using a subtree merge (for example Jakub Narębski’s answer on How do you merge two Git repositories?) and following those instructions mostly works, except that when I commit the subtree merge all of the files from the old repositories are recorded as new added files. I can see the commit history from the old repositories when I do git log, but if I do git log <file> it shows only one commit for that file – the subtree merge. Judging from the comments on the above answer, I’m not alone in seeing this problem but I’ve found no published solutions for it.
Is there any way do merge repositories and leave individual file history intact?
It turns out that the answer is much simpler if you’re simply trying to glue two repositories together and make it look like it was that way all along rather than manage an external dependency. You simply need to add remotes to your old repos, merge them to your new master, move the files and folders to a subdirectory, commit the move, and repeat for all additional repos. Submodules, subtree merges, and fancy rebases are intended to solve a slightly different problem and aren’t suitable for what I was trying to do.
Here’s an example Powershell script to glue two repositories together:
Obviously you could instead merge old_b into old_a (which becomes the new combined repo) if you’d rather do that – modify the script to suit.
If you want to bring over in-progress feature branches as well, use this:
That’s the only non-obvious part of the process – that’s not a subtree merge, but rather an argument to the normal recursive merge that tells Git that we renamed the target and that helps Git line everything up correctly.
I wrote up a slightly more detailed explanation here.