307

I have a server that I'm taking down. The only thing I have left to migrate is my repository. This server is listed as the origin (master) for one of my projects. What is the proper way to move the repository to keep the history.

cjibo
  • 4,487
  • 6
  • 27
  • 34
  • 1
    simply git config remote.origin.url newurl see https://stackoverflow.com/questions/3011402/leaving-github-how-to-change-the-origin-of-a-git-repo – Niels Oct 19 '14 at 21:01
  • 3
    If you wish to migrate your repo and all the branches use the answer by jzwiener or Roberto rather than the accepted answer. – jonnarosey Feb 06 '18 at 14:00
  • All the information (orgin, trunk, etc.) about the repository are stored in a folder named '.git', where you are initializing the repository. So, you need to copy the contents to the new server. – Mansab Uppal Jan 24 '13 at 07:13

18 Answers18

263

To add the new repo location,

git remote add new_repo_name new_repo_url

Then push the content to the new location

git push new_repo_name master

Finally remove the old one

git remote rm origin

After that you can do what bdonlan said and edit the.git/config file to change the new_repo_name to origin. If you don't remove the origin (original remote repository), you can simply just push changes to the new repo with

git push new_repo_name master
Koby
  • 7,267
  • 2
  • 21
  • 16
  • 13
    Would this only copy a single branch from the old repository to the new one? – Andrew Grimm Feb 28 '12 at 23:42
  • 2
    This would yes, but since you, you're just changing the remote, you can push each branch to the new remote. – Koby Mar 02 '12 at 20:49
  • 40
    What is the solution to migrate all branches? – emmby Aug 23 '12 at 22:41
  • @emmby I would look at something like what's done in [this SO answer](http://stackoverflow.com/questions/3846380/how-to-iterate-through-all-git-branches-using-bash-script), and loop through all your branches and push them. – Koby Aug 27 '12 at 19:35
  • 52
    You should be able to push all branches at once via `git push -u new_repo_name --all`. – rmarscher Jun 24 '13 at 19:16
  • 11
    Migration of all branches can be found at http://stackoverflow.com/a/18336145/923599 – jzwiener Aug 20 '13 at 13:32
  • 1
    i prefer the "copy over"/rsync solution as it does not lose e.g. hooks and other configuration. this version does. – mnagel Oct 18 '13 at 08:08
  • 1
    N00b question, but does this also copy the commit history? – Ammar Akhtar Jun 09 '14 at 17:24
  • 1
    git push -u new_repo_name --all does NOT work. I just tried it and it only commits the master branch! – seba.wagner Sep 02 '14 at 02:28
  • 6
    This answer is misleading. The question does not specify that they only wanted master. A user may be under the false impression that this will indeed move the entire repo when it won't. – the_new_mr Jul 23 '15 at 16:33
  • 14
    Instead of editing the git-config file, this command worked for me: `git remote rename new_repo_name origin` – Salim Jul 20 '16 at 08:24
  • Note: `git remote rm` does not delete the remote repository from the server. It simply removes the remote and its references from your local repository. – ecoe Feb 07 '17 at 16:12
  • if you face error fatal: remote origin already exists. , you should do a git remote set-url origin git://new.url.here instead of add – Nicolas D Sep 21 '17 at 09:01
  • Before following your answer, I had to do this on the server where I wanted the repo to go: `git init --bare new_repo_name.git`. Then I followed your instructions and it worked perfectly. Without that, when I tried to `push` I got `fatal: 'new_repo_name.git' does not appear to be a git repository` `fatal: Could not read from remote repository.` You might want to suggest this in your answer. – GlenPeterson Feb 23 '18 at 01:27
  • According to @Koby answer and @rmarscher comment, the shortened version: `git remote rm origin` `git remote add origin new_repo_url` `git push -u origin --all` Note, as @the-new-mr said, this solution works only for local branches. – Danil Valeev May 14 '19 at 09:27
  • looks like it can miss branches. This answer is simple and comprehensive: https://stackoverflow.com/a/26552740/901739 – Dev Null Apr 13 '21 at 21:01
250

Updated to use git push --mirror origin instead of git push -f origin as suggested in the comments.


This worked for me flawlessly.

git clone --mirror <URL to my OLD repo location>
cd <New directory where your OLD repo was cloned>
git remote set-url origin <URL to my NEW repo location>
git push --mirror origin

I have to mention though that this creates a mirror of your current repo and then pushes that to the new location. Therefore, this can take some time for large repos or slow connections.

See also the receipt in section "Extra" of How to move a git repository with history | Atlassian Git Tutorial.

hc_dev
  • 8,389
  • 1
  • 26
  • 38
Roberto
  • 3,487
  • 1
  • 22
  • 24
  • 1
    This is the good solution git remote set-url origin (after having rsync'ed the old origin to the new server/location) – Toni Homedes i Saun Jan 09 '17 at 10:07
  • 22
    Prefer `git push --mirror origin` over `-f`. – Aidiakapi Nov 15 '18 at 18:32
  • 1
    Git version `2.17.1` using `git push -f origin` pushes only the working directory's current branch. @Aidiakapi 's recommendation for `git push --mirror origin` worked for me, pushed all branches, tags, history, etc. – fusion27 Aug 21 '20 at 17:55
  • 1
    There are 2 steps missing, that have to be done first: 1) create a bare remote: sudo git init --bare /path_in_remote/my_repo.git 2) make it writable: sudo chown -R www-data /path_in_remote – Pedro Vicente Jan 30 '22 at 05:50
228

If you want to migrate all branches and tags you should use the following commands:

git clone --mirror [oldUrl]

to clone the old repo with all branches

cd the_repo
git remote add remoteName newRepoUrl

to setup a new remote

git push -f --tags remoteName refs/heads/*:refs/heads/*

to push all refs under refs/heads (which is probably what you want)

jzwiener
  • 8,182
  • 4
  • 21
  • 23
  • 6
    Git was complaining that `--tags` and `refs/heads/*:refs/heads/*` are not compatible with `--mirror`. http://stackoverflow.com/a/26552740/1484831 worked well. – Avigit Oct 24 '14 at 17:07
  • 3
    I used this and it worked for me. Probably should be the elected answer. Note that the "code" you get locally appears to be heavy on the meta data which makes it unclear for newbies if something went wrong. – nick Mar 13 '15 at 23:32
  • 3
    This should be the approved answer. Much better than other solutions – Travis Griggs Nov 04 '15 at 22:25
  • 16
    I ended up with all the branches on my new remote repository prefixed `refs/heads/refs/heads` using `git push -f --tags remoteName refs/heads/*:refs/heads/*` so I have swapped to `git push remoteName --mirror` – dumbledad Jan 10 '16 at 16:17
  • 2
    `push` also supports `--mirror`. `git clone --mirror; cd repo; git push --mirror new_remote` should do the trick – knittl Mar 10 '20 at 06:44
  • too complicated, seems that some have indicated problems. This answer is simpler and problem-free: https://stackoverflow.com/a/26552740/901739 – Dev Null Apr 13 '21 at 21:00
81

Copy it over. It's really that simple. :)

On the client side, just edit .git/config in the client's local repo to point your remotes to the new URL as necessary.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • 6
    You can also simply clone it. Also, instead of directly editing the .git/config file, you can use git remote rm origin; git remote add origin . – ebneter Sep 28 '09 at 06:21
  • 4
    rming the remote will lose any configuration under that section of the config - and cloning it without taking any extra steps will lose branches other than trunk. It's possible to deal with these problems, but, really - just rsync it. – bdonlan Sep 28 '09 at 14:13
  • 1
    What is the solution using only git to do the work? rsync requires additional administrative hoops that are difficult to jump through – emmby Aug 23 '12 at 22:42
  • 3
    this also preserves e.g. hooks and other configuration, so i prefer it to pure git solutions – mnagel Oct 18 '13 at 08:07
76

This is sort of done in parts in some of the other answers.

git clone --mirror git@oldserver:oldproject.git
cd oldproject.git
git remote add new git@newserver:newproject.git
git push --mirror new
Ian Walters
  • 1,769
  • 1
  • 15
  • 9
  • 9
    This is, in fact, the most complete, straight-forward answer. – Lawrence Dol Jun 24 '16 at 22:20
  • 5
    `--mirror` in the push is much important: this should be the correct answer – PaoloC Feb 06 '18 at 15:40
  • 1
    When you initialize the new repository on the new server remember to do a bare init or the push will not be successful: `git init --bare` – marco Oct 01 '19 at 20:23
  • This is the right way, bare repositories pull down the files and all histories across branches. This migrates the entire working history: effectively a like-for-like copy. – Greg Robson Aug 24 '20 at 20:23
  • I have followed the same steps but facing an error: failed to push some refs to "git@newserver:newproject.git" – Nirav Jain Nov 03 '22 at 01:17
37

I'm just reposting what others have said, in a simple to follow list of instructions.

  1. Move the repository: Simply login to the new server, cd to the parent directory where you now want to hold the repository, and use rsync to copy from the old server:

    new.server> rsync -a -v -e ssh user@old.server.com:path/to/repository.git .
    
  2. Make clients point to the new repository: Now on each client using the repository, just remove the pointer to the old origin, and add one to the new one.

    client> git remote rm origin
    client> git remote add origin user@new.server.com:path/to/repository.git
    
Juan A. Navarro
  • 10,595
  • 6
  • 48
  • 52
  • Simple and effective. You can add the flag --bwlimit=XXX if you want to limit the traffic between the servers, where XXX equals the bandwidth in KBytes per second. – Greg Glockner Jan 23 '14 at 04:53
  • 8
    Bit better than remove and add: `git remote set-url origin user@new.server.com:path/to/repository.git` – Chris KL Nov 25 '14 at 01:13
  • For those deploying to a server using git+capistrano, note that I had to use set-url origin in 2 places: on localhost and on the cached-copy that's on the server. – anandvc May 27 '16 at 06:25
16

Take a look at this recipe on GitHub: https://help.github.com/articles/importing-an-external-git-repository

I tried a number of methods before discovering git push --mirror.

Worked like a charm!

John Smith
  • 1,813
  • 4
  • 15
  • 18
10

I followed the instructions on BitBucket to move a repo with all its branches there. Here come the steps with explanations following the # character:

cd path/to/local/repo
git remote remove origin # to get rid of the old setting, this was not in the BitBucket instructions
git remote add origin ssh://git@bitbucket.org/<username>/<newrepo> # modify URL as needed
git push -u origin --all # pushes _ALL_ branches in one go
git push -u origin --tags # pushes _ALL_ tags in one go

Worked nicely for me.

András Aszódi
  • 8,948
  • 5
  • 48
  • 51
10

Please follow the steps:

git remote add new-origin <GIT URL>
git push --all new-origin
git push --tags new-origin
git remote rm origin
git remote rename new-origin origin
Boush
  • 161
  • 1
  • 7
7

This is a variation on this answer, currently suggested by gitlab to "migrate" a git repository from one server to another.

  1. Let us assume that your old project is called existing_repo, stored in a existing_repo folder.

  2. Create a repo on your new server. We will assume that the url of that new project is git@newserver:newproject.git

  3. Open a command-line interface, and enter the following:

    cd existing_repo
    git remote rename origin old-origin
    git remote add origin git@newserver:newproject.git
    git push -u origin --all
    git push -u origin --tags
    

The benefits of this approach is that you do not delete the branch that corresponds to your old server.

Clément
  • 2,358
  • 28
  • 32
6

Should be as simple as:

git remote set-url origin git://new.url.here

This way you keep the name origin for your new repo - then push to the new repo the old one as detailed in the other answers. Supposing you work alone and you have a local repo you want to mirror with all your cruft in it, you might as well (from inside your local repo)

git push origin --mirror # origin points to your new repo

but see Is "git push --mirror" sufficient for backing up my repository? (in all don't use --mirror but once).

Community
  • 1
  • 1
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
4

You can use the following command :

git remote set-url --push origin new_repo_url

Example from http://gitref.org/remotes/

$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)
origin  git://github.com/github/git-reference.git (fetch)
origin  git://github.com/github/git-reference.git (push)
$ git remote set-url --push origin git://github.com/pjhyett/hw.git
$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)
origin  git://github.com/github/git-reference.git (fetch)
origin  git://github.com/pjhyett/hw.git (push)
mrroboaat
  • 5,602
  • 7
  • 37
  • 65
4

follow these instructions If you want to keep all the commits and branches from old to new repo

git clone --bare <old-repo-url>
cd <old-repo-directory>
git push --mirror <new-repo-url>
Extreme
  • 2,919
  • 1
  • 17
  • 27
2

You can use git-copy to duplicate the repo with all histories.

git copy http://a.com/old.git http://a.com/new.git
Quanlong
  • 24,028
  • 16
  • 69
  • 79
1

If you want to move from one origin to another and also keep a backup of your current origin on your local machine you could use these steps:

  1. First locally go to the (git)folder you want to move over
  2. Create the new repository online This step creates a repository where we can push code to

Now in the folder do

git remote get-url origin

The above command gives the current remote origin url, useful to set the origin back to in the last step

git remote set-url origin git@github.newlocation:folder/newrepo.git

The above command sets the remote origin to the new location

git push --set-upstream origin develop

The above command pushes the current active local branch to remote with branchname develop. Of course it preserves all history as with git all history is also pushed.

git remote set-url origin <original old origin>

The above command sets back the remote origin to your current origin: you want this because you are in your existing folder and you probably do not want to mix up your current local folder name with the new folder you are going to create for cloning the repo you just pushed to.

Hope this helps,

Hace
  • 1,421
  • 12
  • 17
0

If you want to migrate a #git repository from one server to a new one you can do it like this:

git clone OLD_REPOSITORY_PATH
cd OLD_REPOSITORY_DIR
git remote add NEW_REPOSITORY_ALIAS  NEW_REPOSITORY_PATH
#check out all remote branches 
for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done
git push --mirror NEW_REPOSITORY_PATH
git push NEW_REPOSITORY_ALIAS --tags

All remote branches and tags from the old repository will be copied to the new repository.

Running this command alone:

git push NEW_REPOSITORY_ALIAS

would only copy a master branch (only tracking branches) to the new repository.

maestr0
  • 5,318
  • 3
  • 28
  • 27
0

I have this bash script written that works as a breeze to migrate my git repo from one server ( one vender , repo hosted in bitbucket ) to another server ( repo hosted in gitlab or local git hosting ) with this command like tool , I only have to authenticate to the new git server where I want to migrate the code from the old repo server.

    #!/bin/bash

# Default values
source_server=""
destination_server=""
source_repository=""
destination_repository=""


# Parse command-line options
OPTS=$(getopt -o "s:d:S:D:" --long source:,destination:,source_repository:,destination_repository: -n 'git-migration' -- "$@")
if [ $? != 0 ]; then
    echo "Failed to parse command-line options. Exiting..."
    exit 1
fi

eval set -- "$OPTS"

# Handle command-line options
while true; do
    case "$1" in
        -s | --source)
            shift
            source_server="$1"
            shift
            ;;
        -d | --destination)
            shift
            destination_server="$1"
            shift
            ;;
        -S | --source_repository)
            shift
            source_repository_link="$1"
            shift
            ;;
        -D | --destination_repository)
            shift
            destination_repository_link="$1"
            shift
            ;;
        --)
            shift
            break
            ;;
    esac
done

# Check if required options are provided
if [[ -z "$source_server" || -z "$destination_server" || -z "$source_repository_link" || -z "$destination_repository_link" ]]; then
    echo "Missing required options. Please provide source server, destination server, and source_repository and destination_repository. Exiting..."
    echo "syntax : migrationtool --source <source_foldername> --destination <destination_foldername> --source_repository <source_Repo_link> --destination_repository <destination_repo_link>"
    echo "Any one option missing will fail the program in the initial phase itself with returncode 121"
    exit 121
fi

#clone the repo first 
git clone $source_repository_link
#list all the branches that are present in the current old repository 
cd $source_server
git branch -a 

# save the list of the branch names into a txt file for further iteration 
git branch -a  | sed s/'remotes\/origin\/'// | grep -v HEAD | grep -v "*" > ../git_branches.txt

# Now we have to checkout each branch to load the data on the folder, in order to see the branch name 
# when we give the command "git branch" this loads only the branches that are checkout mostly
# for this reason this next iteration step is useful
for i in `cat ../git_branches.txt `;do git checkout $i ;done

# fetch all the tags in the old repository 
git fetch --tags

# this shows all the branch and tags that we have fetched for us. 
echo "**********All the tags**********"
git tag
echo "**********All the branches ***********"
git branch -a 

# now if your New repository on the other vendor like github is going to be different then you have to 
# rename the folder name to sync up with repository name that you have created in the github
# mostly the name of the repository is going to be same but here I can use the passing of variable
if [[ -z $destination_server ]];
then 
    cd ..
    mv $source_server $destination_server
    cd $destination_server
fi

# remove the origin from this folder, here only the directory name is matched wrt to the new repository
# but the link to the old repo still exists that we are going to break 
git remote rm origin 
git remote add origin $destination_repository_link

#check the output of the new vender git link 
echo "******* new github vendor link for the project*******"
git remote -v

echo ""
echo ""
# once the origin of the new Git repo is added successfully, then we can push the changes to the new 
# repository vendor 
git push origin --all
git push --tags


## cleanup should be there
cd ..
rm -rf $source_server
rm -rf $destination_server
rm -rf git_branches.txt

Usage : cp script.sh /usr/local/migrationtool

migrationtool  --source old_Git_Repo --source_repository https://gitlab.com/developer123/old_Git_Repo.git
--destination_repository https://github.com/developer123/new_git_Repo.git --destination new_git_Repo

Order of the parameters passed is not required to be correct , just have to make sure that the correct arguments are passed with the parameters.

-1

Remark:

git copy http://a.com/old.git http://a.com/new.git

works only for e.g. a github to github copy, i.e. remaining on the same git system. When copying from e.g. github to gerrit, this does not work.

Besides that, it's quite comfortable, as it copies branches, tags, and submodules automatically.

patman
  • 34
  • 6