Monday, January 19, 2015

Cleanly Moving (Manually) a GIT Repository from One Remote Location to Another

This article is relevant for: 
- GIT 2.2.0
it may or may not work for other versions.

There may come a time in your project lifetime when you may be forced to move your remote GIT Repository from one location to another (this could be a physical switch of servers or just soft endpoint switching of locations, like when you want to move your Repo to a new group or user account etc)

So ideally you want to move your entire GIT project history (commit details, tags etc) to the new location with the intention of using the new location for all future development work and possibly deleting the old location from existence to avoid confusion for developers.

Let's say you want to do this:

We want to copy & move old_repo which has 2 branches called pre-release and master
to a new location to become new_repo which has 2 branches called develop and master 

How can you achieve this cleanly?

There are GIT commands like GIT mirror push etc that could be used, which I've tried but to be honest i've not been able to get my head around it. Also i've read numerous articles of how commands like GIT mirror push having caused plenty of issues for people who used it for backups etc.

So for a recent mass GIT repo migration project I did in my company, I opted to manually move our Repositories one by one and below are the steps I used.

A Disclaimer before we proceed:
Please use the below steps with caution, it worked perfectly for me for my needs but its best you trial it our before actually using it for your projects.

So to achieve the requirement in the image above:

// 1) Firstly make sure your branches in the old_repo are identical
// so as to avoid any confusion (make sure pre-release and master are
// identical), you will be using the remote master branch to make
// the new copy.

// You also need to make sure your new Repo has been set up in
// your remote server, e.g.

// 2) Then clone your existing Repo (which will your old Repo soon)
// into a new folder "new_repo_dev" for example:
git clone new_repo_dev

// 3) Go into new folder:
cd new_repo_dev

// 4) Next you have to manually switch the "origin" entries.
// The below steps do this.

// First you can confirm what origin entered exist by doing this:
git remote -v

// You should see something like this:
origin (fetch)
origin (push)

// Next you remove these entries by doing this:
git remote rm origin

// And then you are the new origin entries like so:
git remote add origin

// And now by running the below again:
git remote -v

// You should see it changed:
origin (fetch)
origin (push)

// 5) Next we have to see if any now obsolete tracking is being
// used on branches and try and remove any pointers to the old Repo.

// ** Please use below steps with high caution, again please test
// before actually implementing on your projects.

// Let's first check what branches are being tracked by running this:
git branch --v

// A clone should only pull your remote master branch so you should
// see something like this:
master 9988925 last commit message

// by looking at this, there does not seem to be any obsolete branch
// tracking set up on this. If there were tracking on branches it would
// look something like:
master 9988925 [origin/master] last commit message

// If you do find any suspicious tracking you can remote it like so
// for each branch:
git branch -d -r origin/master

// You should also remove it from config like so:
git config --unset branch.master.remote
git config --unset branch.master.merge

// Now that we have cleaned out any obsolete branch tracking,
// lets reset fresh branch tracking for the master branch in
// GIT config like so:
git config branch.master.remote origin
git config branch.master.merge refs/heads/master

// 6) Finally, push the new master branch to the new origin like so:
git push origin master

// (and push tags too if you want as well):
git push --tags

// 7) We can now create a new "develop" branch if we want in the new Repo:
git checkout -b develop

// Next push only new develop branch:
git push origin develop

// 8) Finally, track the remote branches to your local branches

// Track your develop branch:
git branch -u origin/develop develop

// And track your master branch (this is automatically done but no
// harm in doing it again):
git branch -u origin/master master

And thats that! Your new Repo is now in the same state as where you left off the old Repo, and your project contributors can continue to work on and push and pull code to the New Repo.

There may be a much quicker way to do this, but as I could not find it I had to manually do this entire process. It worked really well for me on migrating multiple GIT Repos so hope it helps you too.

Any questions or suggestions on how to do this better, please write it in the comments.

Happy Coding Code Junkies!

No comments:

Post a Comment

Fork me on GitHub