Migrating Multiple Folders Between GIT Repositories
07 June 2017
I recently had a situation where I needed to move parts of a GIT repository over to a new repository but wanted to keep all the history from the original repository.
After a bit of searching on google and finding many resources on “the best way to do this,” I ended up hitting a wall. The overall thought patterns I found looked good, but there was no one size fits all “tutorial” for how to do this.
The Eureka Moment
After muddling through (and deleting my local copies of the repository many times!) I finally managed to achieve what I wanted.
A pull request in each repository one deleting the folders with my code, and the other adding them complete with all their history (that second pull request looks very scary with a lot of commits)
But how did I do it I hear you ask…well…this post aims to make this easier for everyone, so keep reading!
The process documented below states all the git bash commands you’r going to need.
Start from any folder you have on disk, we going to leave it clean at the end :)
At various parts in the process, you will need to modify the command to put your own variable content in. These are shown with text in brackets.
Get Your Source/From Repo
To prevent screwing up any local copies of the repo you already have, I suggest a clean pull and remove remote.
git clone (URL-to-from-repo) FromRepo cd FromRepo git remote rm origin
Clean Your Source/From Repo
Since we only want the history to contain certain folders, we can run a command to completely remove everything outside of these folders from history - essentially rewrite history with just the bits we want. - This may take some time if you have a lot of history.
After this, we are done with this repo, for now, so move back up to the root folder.
git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- (folder-paths-space-seperated)' --prune-empty -- --all git reset --hard cd ..
Getting You Destination/To Repo
We need a fresh copy of our destination repository again, this prevents us screwing up any local copy we already have!
git clone (url-to-repo) ToRepo cd ToRepo
Linking Our Repositories
Next, we want to get the Source/From repo into our Destination/To repo onto a branch called “feature/RepoMigrate”
git remote add FromRepo (full-path-of-from-repo) git pull FromRepo master git remote rm FromRepo git branch feature/RepoMigrate git reset --hard origin/master
Pushing Our Migrated Folders
Now we have all our folders in our repo, we can them into our repository and we are then done with this copy of the repository too.
git checkout feature/RepoMigrate git push origin feature/RepoMigrate cd ..
Clean Up Pass 1
So far so good right? - we have got the branch ready to put the important parts of the source/from repository into the new one, so let’s have a tidy up!
rm -rf FromRepo rm -rf ToRepo
Removing Folders From Source/From Repository
We need a fresh copy of the source/from repository to work with to perform these updates and we also want to be on a branch to perform this clean-up
git clone (url-to-from-repo) FromRepo cd FromRepo git branch feature/RepoMigrate git checkout feature/RepoMigrate
Remove and Commit
For each folder you have migrated you want to remove and commit the removal
rm -rf (folder-path-migrated) git commit -a -m 'Remove migrated folder (folder-name) as moved to (new-repo)'
Now Push & Tidy Up
You’re almost done! We just need to push and tidy up.
git push origin feature/RepoMigrate cd .. rm -rf FromRepo
Well, you now have a branch in each repo called “feature/RepoMigrate” one removes the folders and the other adds.
Personally, I raised a pull request onto master for each of these (and had to make some changes to get the CI working correctly in the destination/to repo)