Keeping git history when converting multiple repos into a monorepo
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
You want to make one repository containing both. You can either:
- create a new monorepo, or
- 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.
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
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.
mkdir projects ## or apps or whatever
mkdir packages ## you can use whatever structure you want
Add the existing repos into the new 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