Update: You probably just want to use lerna import. But if you'd like a manual technique, or aren't actually using Lerna, read on.
Let's say you have a Lerna monorepo called acme
. You have a package called app
, presently in its own repository, that you want to move into repo. And you want to preserve the whole git history of app
in the merge, so it becomes part of the history of acme
. The process is actually pretty simple.
acme
looks like this:
acme
|-- package.json
\-- packages
|-- foo
\-- bar
So app
is going to go join foo
and bar
in the pantheon of packages.
Plan ahead, because we are going to do a force-push over acme
's master
branch. Make sure your collaborators know what is about to happen.
The process
You'll need git-filter-repo. Go download that.
- Fork
app
. We're going to push overmaster
of this fork. - Clone your fork of
app
. Thencd app
. - Move the repo's contents into a subdirectory and update history accordingly using
git filter-repo --to-subdirectory-filter "packages/app"
The old contents of theapp
repo should now all be contained inpackages/app
. git push origin master --force
to push this crazy new history over your fork's history.cd
over to theacme
repository- Add your fork of
app
as a remote withgit remote add app git@github.com:you/app.git
git merge app/master --allow-unrelated-histories
- View the
git log
and make sure it looks like you expect it to. - Sweet, forbidden fruit. Savor it:
git push origin master --force
Resolving works in progress
At this point you'll start getting messages from your colleagues asking what horrible thing you've done. You can help guide them a bit.
To update their master
branch, they'll need to check out master, git fetch
and then git reset --hard origin/master
.
If they had a change in progress for app
, they can usegit diff [some commit hash] > mychange.diff
to create a patch file that they can then apply to the acme
repository using git apply mychange.diff
.
If they had a feature branch on acme
, they should be able to use git rebase origin/master -i
to reconcile the histories.
If they just had some uncommitted work on acme
, they should be able to do git stash
, git reset --hard origin/master
, then git stash pop
.
Finishing up
You'll want to adapt app
a little bit to its new home. You'll want to refactor these things (at least) out of app
and into top-level files in acme
:
- .gitignore
- ESLint config
- Prettier config/ignore
- Travis config
- Dev dependencies from
app/package.json