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 ../ with the relative path to the source repository:

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.