Keeping git history when converting multiple repos into a monorepo

Chris Thompson
2 min readDec 5, 2022

--

Monorepos are all the rage. You may be looking to convert your many packages and projects into a single repo, but you still want to keep your git history.

TLDR; add a remote for each repo and use git merge remote/main --allow-unrelated-histories

Let’s assume I have the following:

> ls ~/dev
my-app
my-packages

You want to make one repository containing both. You can either:

  1. create a new monorepo, or
  2. use an existing one as the base for your monorepo

The important steps here are basically the same whichever way you go.

Move the files in your repos into new directories

I’m going to put my applications and servers into projects and packages and libraries into packages . The directory structure is arbitrary and you can do whatever you want.

cd ~/dev/my-app
mkdir -p projects/my-app
git mv -k * projects/my-app ## -k is used to ignore the error that it can't move the projects directory
git mv -k .* projects/my-app ## .* to move .gitignore and other dot files
git commit -m "chore: move all files into projects/my-app"

and do the same with you other repos

cd ~/dev/my-package
mkdir -p packages/my-package
git mv -k * packages/my-package
git mv -k .* packages/my-package
git commit -m "chore: move all files into packages/my-package"

Create a new monorepo (or use an existing one)

If you are using an existing repo, like my-app just skip this first part.

cd ~/dev
mkdir monorepo
cd monorepo
git init
mkdir projects ## or apps or whatever
mkdir packages ## you can use whatever structure you want

Add the existing repos into the new monorepo:

cd ~/dev/monorepo
git remote add -f my-app ../my-app ## -f to fetch the repo state, needed to do the merge later
git remote add -f my-package ../my-package ## you can also like to a github remote as normal
git merge my-app/main --allow-unrelated-histories
git merge my-package/main --allow-unrelated-histories

And you’re done. You can remove the remotes

git remote remove my-app
git remote remove my-package

Enjoy your new monorepo!

--

--