There's no simple fix, but there is a really well written guide here (Move files from one repository to another, preserving git history) by Ayushya Jaiswal and I'll quote it in this post for archival purposes.
tl;dr: You're essentially re-basing a repo (safely) and extracting just the file(s) that you want. Then pulling the git history from your rebased repo into whatever repo you're currently working on.
Notes before you get started:
You'll need https://stackoverflow.com/a/56334887/929999 for this as well, if you want a specific file. I'll add a disclaimer below in the quoted guide where to add in this step.
Here's the quoted text from the article:
Getting files ready to move from Repository A.
Step 1: Make a copy of repository A as the following steps make major changes to this copy which you should not push!
mkdir cloneA
cd cloneA
git clone --branch <branch> --origin origin --progress \
-v <git repository A url>
# eg. git clone --branch master --origin origin --progress \
# -v https://github.com/username/myproject.git
# (assuming myprojects is the repository you want to copy from)
Step 2: Go to that directory.
cd <git repository A directory>
# eg. cd myproject
# Folder Path is ~/cloneA/myproject
Step 3: To avoid accidentally making any remote changes (eg. by pushing), delete the link to the original repository.
git remote rm origin
This is the step to modify, modify it by doing the git filter-branch --prune-empty ... $FILES
step from here instead, that will extrapolate only your desired files. The rest should be the same.
In your case, it would be something like this:
FILES='/a/b/c/d'
git filter-branch --prune-empty --index-filter "
git read-tree --empty
git reset \$GIT_COMMIT -- $FILES
" \
-- --all -- $FILES
Step 4: Go through your history and files, removing anything that is not in FOLDER_TO_KEEP
. The result is the contents of FOLDER_TO_KEEP
spewed out into the base of repository A.
git filter-branch --subdirectory-filter <directory> -- --all
# eg. git filter-branch --subdirectory-filter subfolder1/subfolder2/FOLDER_TO_KEEP -- --all
Step 5: Clean the unwanted data.
git reset --hard
git gc --aggressive
git prune
git clean -fd
Step 6: Move all the files and directories to a NEW_FOLDER which you want to push to repository B.
mkdir <base directory>
#eg mkdir NEW_FOLDER
mv * <base directory>
#eg mv * NEW_FOLDER
Alternatively, you can drag all the files and directory to the NEW_FOLDER using GUI.
Step 7: Add the changes and commit them.
git add .
git commit
Merge the files into the new repository B.
Step 1: Make a copy of repository B if you don’t have one already.
mkdir cloneB
cd cloneB
git clone <git repository B url>
# eg. git clone
https://github.com/username/newproject.git
Step 2: Go to that directory.
cd <git repository B directory>
# eg. cd newproject
# Folder Path is ~/cloneB/newproject
Step 3: Create a remote connection to repository A as a branch in repository B.
git remote add repo-A <git repository A directory>
# (repo-A can be anything - it's just a random name)
# eg. git remote add repo-A ~/cloneA/myproject
Step 4: Pull files and history from this branch (containing only the directory you want to move) into repository B.
git pull repo-A master --allow-unrelated-histories
# This merges master from repository A into repository B
Step 5: Remove the remote connection to repository A.
git remote rm repo-A
Step 6: Finally, push the changes
git push
You can delete both the cloned repositories.
The files changes with history are now available online in repository B.