There are two tools available to move files and directories between Git repositories while presering history:
filter-branch
filter-repo
(official site)filter-branch
is an older built-in tool, but Git no longer recommends using it. It’s slow and prone to errors. In this article, we will use filter-repo
, a modern and effient tool for the task.
In this demo, we will move the directory hello/world
from source.git
to target.git
while preserving its commit history.
Filter the source directory along with its history and push the result, then fetch it into the target and merge the result.
filter-repo
First, ensure you have Python and pip
installed on your system. Then, install git-filter-repo
tool with:
pip3 install git-filter-repo
Filter the source directory along with the history.
Create a new branch in the source repository to work with:
cd /path/to/source-repository
git checkout main
git pull
git checkout -b temp-branch
Next, filter out the desired path. The following command will remove all files and directories except hello/world
:
git filter-repo --path hello/world --force
Now, push the filtered branch to the target repository:
git remote add target <target-repo-url>
git push target temp-branch
In the target repository, pull the new branch:
cd /path/to/target-repository
git pull origin
git checkout temp-branch
Now, merge the branch into main
branch:
git checkout main
git merge temp-branch --allow-unrelated-histories
If there are conflicts, resolve them, then push the changes:
git push origin main
--invert-paths
: Invert the selection of files from the specified –path-{match,glob,regex} options below, i.e. only select files matching none of those options.
git filter-repo --path <file-or-directory-path> --invert-paths
Using git filter-repo
, we can effectively move specific files or directories between repositories whil preserving their history. This method allows for flexible, clean history management with including unnecessary files.