Migrating code from one Git repository to another while keeping the history
Within the software development community, there is often a debate about keeping your code in a single monorepo or splitting it into multiple smaller repositories. This article will not discuss the advantages and disadvantages of one approach over the other. It will show you how to migrate code between Git repositories safely when you need to do so.
Step 1: Install git-filter-repo
While Git has the filter-branch
command, its authors no longer recommend its usage due to its many limitations and risks. Instead, the Git documentation of the filter-branch
command redirects you to an open-source tool called git-filter-repo
. Install this tool using the command below.
curl https://raw.githubusercontent.com/newren/git-filter-repo/main/git-filter-repo > git-filter-repo
chmod +x git-filter-repo
Step 2: Make a fresh clone of the source repository
Use git clone
to make a fresh copy of the repository from which you want to migrate files. We will use this repository to extract the necessary parts of the Git history without damaging or changing your development version.
Step 3: Extract relevant history
Run git-filter-repo
from the source repository's root directory to remove everything unrelated to the files you want to migrate to another repository.
git filter-repo --subdirectory-filter <name of the directory you want to migrate>
The above command removes all files not in the given directory from the repository and their associated Git history. It also removes the directory and moves all its child files and directories to the repository's root. Often, this is not what you want, so you can run another git filter-repo
command to move the files to the proper subdirectory.
git filter-repo --to-subdirectory-filter <new subdirectory>
Now, the files in the source repository are ready to be migrated to the target repository.
Step 4: Pull in the source files in the target repository
As with the source repository, create a fresh clone of the target repository, using git clone
, before you run any commands.
Next, we'll add a remote to our target repository and point it to the modified source repository we created in the previous step.
git remote add source-repository <path to source repository on your local machine>
Fetch the history from the source repository using a git pull
command. (below, we assume that you were on the main
branch in the source repository)
git pull --allow-unrelated-histories --no-rebase source-repository main
That's it. The files from the source repository have been added to the target repository while keeping the Git history intact.
Step 5: Push your changes to the remote
As a final step, once you've double-checked everything, use git push
to push the changes you made to the remote repository.