Say you have two git repositories that you want to combine into one.
Maybe you’re assembling a monorepo, or maybe you’ve decided your standalone tool/library shouldn’t be standalone any more. Whatever the reason, you almost certainly don’t want to lose your commit history.
So here’s how:
TL;DR
$ cd $targetRepoDir
$ git remote add $sourceName $sourceOrigin
$ git fetch $sourceName
$ git merge --allow-unrelated-histories $sourceBranch
How?
The important thing to realise is that while a git repository contains a graph of commits, the graph doesn’t need to be fully connected - you can have multiple distinct unconnected trees. If you’ve ever used GitHub Pages for a project then you’ve exploited this - it creates a totally disconnected gh-pages
branch.
With that in mind, the whole process is fairly straightforward:
First, start with your target repo, and fetch in the commits from your source repo
$ cd $targetRepoDir
$ git remote add $sourceName $sourceOrigin
$ git fetch $sourceName
Now your target repo has both trees in it
At this point, you might want to tweak your source a little (e.g. moving it into a subdirectory, shifting files around to avoid collision etc.)
$ git checkout $sourceBranchName
$ # Do your thing
$ git commit
Now go back to your target branch, and merge in the source!
$ git merge --allow-unrelated-histories $sourceBranchName
Voilà!
So?
Fancy things like subtree merges exist, and I’m sure there’s a neat one-liner that’ll do the whole shebang. For me this is a rare enough need that I’m likely to have forgotten the magic incantation, doing it “manually” costs little extra, and inevitably I want to fiddle with the source repository a little in the middle.
I find the whole process a nice reminder of the quite elegant and simple system at the heart of git.
Thanks to Olivier Verdier for the StackOverflow answer that led to this