This post shows how to use git subtree commands to move git repositories around.
Perfect if you’re indecisive about monorepo vs multirepo.
Move a repo in a different repo as a subfolder
Use case: you want to move a library into a monorepo (because you read a post that says it’s cool).
Before:
Source repo Destination repo
| |
|-- src |-- packages
| \-- index.ts | \-- bar
|-- package.json \-- README.md
|-- package-lock.json
\-- README.md
After:
Destination repo
|
|-- packages
| |-- bar
| \-- foo (**moved here from source repo**)
| |-- src
| | \-- index.ts
| |-- package.json
| |-- package-lock.json
| \-- README.md
\-- README.md
Steps:
- Clone the source repo in a folder named
source - Clone the destination repo in a sibling folder named
destination - In the destination repo, run:
git subtree add -P packages/foo ../source master(assuming the main branch is calledmaster) - Delete the source repo (I’m sure you won’t regret it)
Move a subfolder to a new repo
Use case: you want to move a library out of a monorepo into its own dedicated repo (because you read a different post that says monorepos are actually not cool).
Before:
Source repo
|
|-- packages
| |-- bar
| \-- foo
| |-- package.json
| \-- README.md
\-- README.md
After:
Destination repo (**keeping only the contents of foo**)
|-- package.json
\-- README.md
Steps:
- Clone the source repo in a folder named
source - Prepare a new empty bare repo in a folder named
destination(withgit init --bare) - In the source folder, run
git subtree push -P packages/foo ../destination master - To double check everything went fine, you can clone the bare repo into a regular repo and inspect its contents.
- Delete the library from the source repo
Move a subfolder to an existing repo
Use case: you have two monorepos and you want to move one library from one to the other (because the oxymoron of having multiple monorepos escapes you).
Before:
Source repo Destination repo
| |
|-- packages |-- libs
|-- bar \-- bar
\-- foo
After:
Source repo Destination repo
| |
|-- packages |-- libs
\-- foo |-- bar
\-- bar_v2 (** moved here from source repo where it was called bar **)
- Clone the source repository into a folder named
source - Clone the destination repository into a sibling folder named
destination - In the source repo, keep only the desired library with
git subtree split -P packages/bar -b temp(temp is the name of a branch we’ll use next) - Checkout the
tempbranch and double check the source repo folder only has the desired library - In the destination repo, add the library with
git subtree add -P libs/bar_v2 ../source temp - Delete the library from the source repo
Update: 2021-10-03
I have a put together a script that handles some of these cases (especially the moving back to multirepo part).