Skip to content

Subtree

Eric Bouchut edited this page Apr 12, 2021 · 16 revisions

Split a Git Repository

Assuming we have a monorepo named client-server-repo.
It is a single git repository, containing the code for 2 projects, ie. both the server and the client code.
We want to split the repository into 2 distinct repositories, extracting the client code in a new repository (client-repo) and keep only the server code in the original repository. Ultimately, at the end of this process, we will rename the source repository server-repo.
Using git subtree this can be done like so:

  1. Extract the folder and its commits into a new branch
  2. Create a new repository and push the extracted code there
  3. Remove the extracted folder from the source repository and replace it with a subtree dependency

Extract a Folder into a new Branch

First thing is to extract the client code in a new branch named for instance client.

The below command splits the client/ folder in a client branch and replays there all the commits related to the client/ folder.

cd $DEV/client-server-repo

git checkout master
git subtree split --prefix=client -b client

where:

  • --prefix=client denotes the folder to extract
  • -b client denotes a new branch in the current repository where to store the extracted folder/commits

Let's now push the client branch to a new repository.

Create a new Repository out of the Extracted Branch

# Create the new client-repo repository
cd $DEV
mkdir client-repo
cd client-repo
git init --bare

# Push the extracted `client` branch to the new `client-repo` repository
cd $DEV/client-server-repo
git push $DEV/client-repo client:master

# Push the `master` branch from the `client-repo` local repository to the remote `origin` repository
cd $DEV/client-repo
git remote add origin [email protected]:ebouchut/client-repo.git
git push origin master

Remove the Extracted folder and "Replace" it with a Subtree Dependency

# Remove the extracted folder `client`
cd $DEV/client-server-repo
git rm -r client/
git add -A
git commit -m "Remove client folder" -m "Extracted in its own repository: client-repo"

# "Replace" the extracted folder with an external dependency to the `client-repo` repository
cd $DEV/client-server-repo
git remote add client [email protected]:ebouchut/client-repo.git
git subtree add --prefix=client client master

where:

  • --prefix=client defines the folder (where to bring back the subtree)
  • client denotes the name of the remote repository for the client project
  • master denotes the branch to use from the client remote

TODO: See https://lostechies.com/johnteague/2014/04/04/using-git-subtrees-to-split-a-repository/