Preserve commit history when moving files across Git repositories
When managing projects in Git, there may come a time when you need to transfer specific files or directories, along with their entire history, from one repository to another. This can be a useful process when reorganizing your codebase, separating concerns, or simply consolidating repositories. In this blog post, we’ll explore a step-by-step guide to achieve this task seamlessly.
Step 1: Clone or Copy the Source Repository
Start by accessing your source repository — the one containing the files and history you want to move. You can either clone it from your remote origin or copy your local repository if you already have it on your system. You want a copy separate from your working local repository, as we’ll be doing some history rewriting.
Step 2: Remove the Origin Remote
To prevent any accidental pushes to your origin, remove the remote origin by running the following command:
git remote rm origin
This step ensures that you won’t inadvertently propagate any history rewriting to the original repository.
Step 3: Keep the history of only the files and folders you want to move across
Now, you’re ready to filter and preserve the history of the specific file or directory you want to move. Use the following command:
git filter-branch --subdirectory-filter path/to/dir-or-file -- --all
If there is no commit history of those files in the branch you are currently in, the command may abort with a “Found nothing to rewrite” message. In such cases, you can use the following command, which is also handy when you have multiple paths to preserve:
git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- path/to/dir1 path/to/dir-or-file-2' --prune-empty -- --all
This command filters the repository’s history to keep only the files and directories you specified.
Step 4: Clean Up
After filtering, clean up any remaining artifacts from the history rewrite:
git reset --hard
git gc --aggressive
git prune
git clean -fd
These commands ensure that your repository is in a clean state following the history modification.
Step 5: Add a Local Remote to the Source Repository
Now, switch to your target repository—the one where you want to move the files and history. Add a local remote pointing to the source repository you cloned or copied earlier. Replace with a meaningful name and ../
git remote add <source> ../<sourcedir>
Step 6: Pull Files and History from the Source
Use the following command to pull the files and history from the source repository into your target repository, using the remote name you specified:
git pull <source> <branch you want to pull from> --allow-unrelated-histories
This command merges the source repository’s history into your target repository, preserving both histories.
Step 7: Remove the Local Remote
After the merge is successful, you can remove the local remote pointing to the source repository:
git remote rm <source>
Step 8: Commit and Push
Finally, commit the changes to your target repository with a descriptive message:
git commit -m "Moved folders from other repository"
Push the changes to update your remote repository:
git push
Now, you can delete those files and folders from your source repository.
You’ve successfully moved files and their entire history from one Git repository to another. This process allows you to maintain a clean and organized codebase while preserving valuable historical data.
- Now Generating URL Slugs With Natural Language Processing!
- Safe Storage of App Secrets in Python Development
- Automate All The Things: A Manifesto for Building Better Teams
- Preserve commit history when moving files across Git repositories
- Publishing a Jekyll site to a separate Github Pages repository using Github Actions