Kristian Glass - Do I Smell Burning?

Merging two git repositories

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

Comments