How To Migrate A Git Repository To A New Server

Admittedly, it took me a while (and a couple of attempts) to clone a bunch of git repos from an old server and put them up on a new one. These are the steps I took to copy a working git repository from the old server and put it up on another server complete with history, branches, and tags.

Clone original repo

git clone <original url>:<repo name>;

Set up repo on git server

If your remote is a Gitosis server, make sure that the new project you will be migrating is set up on gitosis.conf. For more information on Gitosis, click here.

...
[group project-group]
writable = some-other-project, project
members = you, other-guy
...

Go to the newly cloned git repo folder

cd <path to cloned repo folder>;

Check which branch you’re on. make sure you’re on the master branch.

git checkout master; git branch -a;

Track all remote branches

There’s more than one way to do this, but let’s follow the bash script from here.

for remote in `git branch -r | grep -v master `; do git checkout --track $remote; done;

Change remote url to new repo url

git remote set-url <'origin' or remote name> <new url>:<project name>;

Push everything to new repo (includes all branches and tags)

git push <--f> --all <'origin' or remote name> <-u>; git push --tags;
  • –all will push all the local and/or tracked branches.
  • -u will automatically set upstream, so your repo is linked to the remote one automatically. This means that you don’t have to include the remote repo and branch in the commands whenever you push and pull.
  • –f means forced, if the project already exists in the git server and you want to overwrite it. ONLY do this if you’re sure it doesn’t affect anyone or anything else.

Example

git clone git@old.com:project;
cd project;
git checkout master;
for remote in `git branch -r | grep -v master `; do git checkout --track $remote; done;
git remote set-url origin git@new.com:project;
git push --all origin -u; git push --tags;

Migrating A Lot of Repos Made Easier

Mmmhmm…that can be such a pain in the backside. Good thing, you can write some code to alleviate some tediousness in this task.

All you have to do is create an array (or a similar collection) of the repository names you would like to migrate. If you’re using Gitosis, you could perhaps copy paste the writable line after “writable = ” and split them into an array (using an empty space ” ” as the delimiter).

Next, you would have to loop through the array and print out a line that would resemble the command. Something like..

System.out.print("git clone git@" + oldRepoUrl + ":" + repoName + ";  ");

Just run your code and you should come up with a long script that you can copy paste to the terminal/command prompt (For this, I suggest you create a new folder and work there). You can either print and run ALL the commands at once or do each of them one by one. I myself printed and ran several commands separately to make sure things were in their proper place before moving on to the next step.

Important: In your code, once you move from repo to repo, don’t forget to add code that will take you to the directory of the next repo.

System.out.print("cd ../" + repoName + "; ");

5 comments

  1. stav says:

    Thanks for the good info.

    I used this:

    for remote in `git branch -r | grep -v master`; do git branch –track ${remote#origin/} $remote; done
    git fetch –all
    git push –all origin

  2. Todd Ellner says:

    Many thanks. Your article was very useful

  3. Todd Ellner says:

    Taking a further look around I wonder decided against using
    git clone –bare
    and
    git push –mirror

    • Ria Maria says:

      When I was moving lots of git repositories at the time, most (if not all) repos had remote branches and I focused on making sure all branches and tags were included in the move (and totally overlooked –mirror & –bare during research time).

      Though I’m not inclined to try it out at the moment, I’ve read that git clone –mirror and git push –mirror may be able to automatically fetch the remote branches and tags (correct me if I’m wrong). This post talks about how to use git clone –mirror & git push –mirror.

      So yeah.. git clone –mirror might be better suited for the job than git clone –bare (according to this StackOverflow answer). If you try git clone –mirror instead of tracking all remote branches, please let me know how it goes :D

  4. Todd Ellner says:

    Make that “I wonder why you decided”

Leave a Reply

Your email address will not be published. Required fields are marked *