Move files from one repository to another, preserving git history
In the multi-repository project structure, its only a matter of time when you’ll want to refactor some files from one project to another.
Today at Instamojo.com we reached a point when we start to split our large repository into several small sub-projects.
When we simply try to move files from one repository to another we lose the entire history of that particular file, and we can’t trace it back anymore.
Moving the files with history to a different repository requires the following steps:
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 cloneAgit 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
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_FOLDERmv * <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 cloneBgit 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.