An example to filter out a subset of blobs/trees in a Git project, retain the history, and merge it into another Git project.
The task
I got this task to merge some directories and files from Project A into a subdirectory in Project B, and keep the related commit history in Project A.
To state this more clear let's assume I need to move subdir1
and file1
of the below Project A into Project B.
Project A
/
/subdir1
/subdir2
/file1
/file2
Project B
/
/otherdirs
/otherfiles
The result I want in project B is:
/
/project_a
/subdir1
/file1
/otherdirs
/otherfiles
And all the commit history related to subdir1
and file1
should be kept.
Steps
Prerequisites
Install git-filter-repo
from [here][git-filtere-repo].
Prepare the paths to merge in Project A
First, get a new clone of Project A. This is a destructive operation that will rewrite the history of the repository completely. So make sure you have a backup of the origin Project A.
Filtere out the trees and blobs we want to keep into a subdirectory project_a
.
git checkout main
git filter-repo --path subdir1 \
--path file1
--to-subdirectory-filter project_a
This will rewrite this repository to contain only subdir1
and file1
under the directory project_a
.
If we want all files in Project A.
We can just move all files into the directory project_a
like this.
git checkout main
git filter-repo --to-subdirectory-filter project_a
Merge the subtree to Project B
# Add the filtered repository as a remote and fetch the objects.
git remote add -f project_a ../project_a/
# Merge the project A repository but do not commit.
git merge --allow-unrelated-histories -s ours --no-commit project_a/main
# Add the subtree project_a to the index.
git read-tree --prefix=project_a/ -u project_a/main:project_a
# Commit the merge.
git commit -m "merge files from Project A"