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
my-app
my-packages
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.
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