Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Moving git repository and all its branches, tags to a new remote repository keeping commits history
#!/bin/bash
# Sometimes you need to move your existing git repository
# to a new remote repository (/new remote origin).
# Here are a simple and quick steps that does exactly this.
#
# Let's assume we call "old repo" the repository you wish
# to move, and "new repo" the one you wish to move to.
#
### Step 1. Make sure you have a local copy of all "old repo"
### branches and tags.
# Fetch all of the remote branches and tags:
git fetch origin
# View all "old repo" local and remote branches:
git branch -a
# If some of the remotes/ branches doesn't have a local copy,
# checkout to create a local copy of the missing ones:
git checkout -b <branch> origin/<branch>
# Now we have to have all remote branches locally.
### Step 2. Add a "new repo" as a new remote origin:
git remote add new-origin git@github.com:user/repo.git
### Step 3. Push all local branches and tags to a "new repo".
# Push all local branches (note we're pushing to new-origin):
git push --all new-origin
# Push all tags:
git push --tags new-origin
### Step 4. Remove "old repo" origin and its dependencies.
# View existing remotes (you'll see 2 remotes for both fetch and push)
git remote -v
# Remove "old repo" remote:
git remote rm origin
# Rename "new repo" remote into just 'origin':
git remote rename new-origin origin
### Done! Now your local git repo is connected to "new repo" remote
### which has all the branches, tags and commits history.
@jpjoyal

This comment has been minimized.

Copy link

commented Aug 4, 2015

this might be handy too
for remote in git branch -r; do git branch --track $remote; done

@okram999

This comment has been minimized.

Copy link

commented Aug 10, 2015

@jpjoyal - i hope your command creates the local branches for the remotes, if not exist. Instead of going through all the remotes manually with

git checkout -b origin/

Unfortunately the command doesn't work .. Look at this http://stackoverflow.com/questions/379081/track-all-remote-git-branches-as-local-branches

@eirikb

This comment has been minimized.

Copy link

commented Oct 30, 2015

Must ask, why not just git push --mirror?

@niksumeiko

This comment has been minimized.

Copy link
Owner Author

commented Dec 2, 2015

@eirikb, there's an explanation, why git push --mirror alone doesn't make the job.

@okram999, git fetch origin fetches all the remote branches, and then you have to git checkout -b <branch> origin/<branch>, if some of the remote branches doesn't have a local copy – it's mentioned in the script.

@RoSk0

This comment has been minimized.

Copy link

commented Dec 4, 2015

Personally I think that it's much better to do it this way:

git clone --mirror URL
git remote add NEW-REMOTE URL
git push  NEW-REMOTE --mirror 
@matm

This comment has been minimized.

Copy link

commented Dec 4, 2015

Thanks @RoSk0, works perfectly. However, cd in the bare directory is needed before adding the remote and pushing.

@prashathsenthil

This comment has been minimized.

Copy link

commented Dec 7, 2015

@RoSk0 can you please specify where to run these commands... do i need to cd into new repo and run those?

@vikas027

This comment has been minimized.

Copy link

commented Feb 13, 2016

@prashathsenthil You have to run these commands as below

git clone --mirror <url_of_old_repo>
cd <name_of_old_repo>
git remote add new-origin <url_of_new_repo>
git push new-origin --mirror
@DowerPower

This comment has been minimized.

Copy link

commented Mar 8, 2016

If you have multiple branches, you'll want to add git fetch before add the new origin

@natsu90

This comment has been minimized.

Copy link

commented Mar 22, 2016

Thanks @vikas027 @RoSk0 that works

@GeekInTheNorth

This comment has been minimized.

Copy link

commented Apr 18, 2016

Thank you all, this worked a treat for me.

@ashiquehssn

This comment has been minimized.

Copy link

commented Apr 19, 2016

I want create a local copy of repository from the history not from the current. i.e I want to fetch from the 2 months ago commit. Please help me

@GPrathap

This comment has been minimized.

Copy link

commented May 18, 2016

Thanks guys it works

@bradhill99

This comment has been minimized.

Copy link

commented Jul 3, 2016

I have the same requirement like @ashiquehssn, I like to mirror a github project from a specific commit, not sure what to do. Can anyone help? Thanks.

@douglasdeodato

This comment has been minimized.

Copy link

commented Jul 26, 2016

very useful 👍

@tortal

This comment has been minimized.

Copy link

commented Aug 26, 2016

Maybe change from bash to /bin/sh ? Since this script is not using any shell commands really it would be false to exclude tcsh as interpreter (if let's say sh was symlinked to tcsh)..

@dorelljames

This comment has been minimized.

Copy link

commented Sep 6, 2016

I followed @vikass02's just like below:

Counting objects: 1011, done.
Compressing objects: 100% (456/456), done.
Writing objects: 100% (1011/1011), 2.52 MiB | 421.00 KiB/s, done.
Total 1011 (delta 521), reused 1011 (delta 521)
remote: Resolving deltas: 100% (521/521), done.
To git@github.com:dorelljamesORG/newrepo
 * [new branch]      hey -> hey
 * [new branch]      master -> master
 ! [remote rejected] refs/pull/1/head -> refs/pull/1/head (deny updating a hidden ref)
 ! [remote rejected] refs/pull/1/merge -> refs/pull/1/merge (deny updating a hidden ref)
error: failed to push some refs to 'git@github.com:dorelljamesORG/newrepo'

However, I get errors with the pull requests being rejected. Wondering why?

@traveling-desi

This comment has been minimized.

Copy link

commented Sep 10, 2016

HI!

How can I move a git repository (say A) on github under another git repository (say B). I don't mind if A doesn't stay as a repository and just becomes a subdirectory under B (and in the process loses all commit history.) I want to be able to do this directly on github and not clone/fetch locally on my machine and then push it back to github (since this is expensive and takes long time.)

What I am asking is just switching pointers (unix mv) instead of moving the whole data (unix cp)

Thanks

@faizan80

This comment has been minimized.

Copy link

commented Dec 8, 2016

IMO, there is problem with this piece of code:
git checkout -b origin/

You are actually creating a new branch called "origin/branchName" from your current reference. This is not same as your remotes/origin/branchName ;)
Also when you do git push --all, you are creating a remote branch called "remotes/origin/origin/branchName" ;)

I, actually, did some over-engineering here.

for remote in $(git branch -r); do
if [[ "${remote}" != "origin/HEAD" ]]; then
echo "git checkout -b ${remote:7};"
git checkout ${remote:7}
fi
done

@pablitoc

This comment has been minimized.

Copy link

commented Dec 15, 2016

Thanks for the write up. I was able to move a simple repository from bitbucket to Github using these steps.

@replay111

This comment has been minimized.

Copy link

commented Feb 5, 2017

How to push to new repository not all change, but only changes to some specified commit?
Is it possible to migrate only part of old repository?

@stocksnut

This comment has been minimized.

Copy link

commented Feb 21, 2017

Thank you @vikas027 that works good

@stalebbeik

This comment has been minimized.

Copy link

commented Jun 13, 2017

@niksumeiko Thanks for your post and the link to the article. I hit the exact same problem when I used the --mirror option while attempting to transfer a large repository from gerritt to github. The --mirror option did not transfer all the branches.

I first established the local branches using "git branch --track branchname origin/branchname".
Then I used the "git push --all " and "git push --tags "" sequence to push to gerrit.

@shalinijeevanigi

This comment has been minimized.

Copy link

commented Jun 22, 2017

@vikas027, thanks for the clear and detailed steps.

@bennygenish

This comment has been minimized.

Copy link

commented Jul 19, 2017

@vikas027, Works great. Thank you so much!

@igorrodygin

This comment has been minimized.

Copy link

commented Aug 26, 2017

@niksumeiko, Thank you!

@greenRoberto

This comment has been minimized.

Copy link

commented Sep 10, 2017

Thanks!!

@Dhaval2404

This comment has been minimized.

Copy link

commented Oct 10, 2017

Thank you so much..!!!

@danielpsf

This comment has been minimized.

Copy link

commented Nov 9, 2017

Tks @RoSk0, worked like a charm 😉

@fthzkrtn

This comment has been minimized.

Copy link

commented Dec 17, 2017

Thank you @RoSk0. Saved my day 👍

@BalmungSan

This comment has been minimized.

Copy link

commented Jan 25, 2018

Thanks

@kvsuresh

This comment has been minimized.

Copy link

commented Jan 30, 2018

thanks

@kvsuresh

This comment has been minimized.

Copy link

commented Jan 30, 2018

Any solution?

! [remote rejected] refs/tmp/0062e6ce3781bc91cecc46f0283d7f1f/head -> refs/tmp/0062e6ce3781bc91cecc46f0283d7f1f/head (deny updating a hidden ref)
! [remote rejected] refs/tmp/04fc2a880d4c7991aa2288978f7911e5/head -> refs/tmp/04fc2a880d4c7991aa2288978f7911e5/head (deny updating a hidden ref)
! [remote rejected] refs/tmp/0559724903d8e9d65c4e3f4b71d69407/head -> refs/tmp/0559724903d8e9d65c4e3f4b71d69407/head (deny updating a hidden ref)

@jhhyj1010

This comment has been minimized.

Copy link

commented Mar 13, 2018

Hi Sumeiko,
How can I proceed if old repository has some large files? I encountered some errors due to large files pushing failure.
$ git push new-origin --mirror
Counting objects: 162100, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (78354/78354), done.
Writing objects: 100% (162100/162100), 563.10 MiB | 1.61 MiB/s, done.
Total 162100 (delta 50864), reused 162069 (delta 50836)
remote: Resolving deltas: 100% (50864/50864), done.
remote: warning: File rax/rau/src/main/java/com/sybase/ra/lr/udb/ni/compiled_libs/hpia64/udb_hpia64_files.tar is 96.10 MB; this is larger than GitHub Enterprise's recommended maximum file size of 50.00 MB
remote: warning: File rsngroot/container/src/test/resources/com/sybase/rs/stablequeue/diskpersistent/test/SQMF_120625.0833.45009-0700.dat is 96.71 MB; this is larger than GitHub Enterprise's recommended maximum file size of 50.00 MB
remote: warning: File rsngroot/container/src/test/resources/com/sybase/rs/stablequeue/diskpersistent/test/SQMF_120625.0833.45009-0700.dat is 96.65 MB; this is larger than GitHub Enterprise's recommended maximum file size of 50.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: File rax/rau/src/main/java/com/sybase/ra/lr/udb/ni/compiled_libs/rauni.tar.gz is 102.82 MB; this exceeds GitHub Enterprise's file size limit of 100.00 MB
remote: error: File rsngroot/container/src/test/resources/com/sybase/rs/stablequeue/diskpersistent/test/LargeMessagesTestMsgFile.dat is 163.75 MB; this exceeds GitHub Enterprise's file size limit of 100.00 MB
remote: error: File rsngroot/capture/src/test/resources/com/sybase/rs/capture/ltlparser/test/knight.mdr.log is 827.78 MB; this exceeds GitHub Enterprise's file size limit of 100.00 MB
To github.wdf.sap.corp:I312651/rsng.git

@Rktedlapu

This comment has been minimized.

Copy link

commented May 11, 2018

Hi, Can you please address above issue, i am also facing same issues when migrating codehub to github

@pmacca

This comment has been minimized.

Copy link

commented May 12, 2018

To resolve the issue with large files, use the BFG tool - https://rtyley.github.io/bfg-repo-cleaner/

Github has a hard limit of ~100MB on individual files when importing / pushing repos.

@vinnyasa

This comment has been minimized.

Copy link

commented May 21, 2018

Thank you @niksumeiko this was super useful.

@lillypad

This comment has been minimized.

Copy link

commented May 27, 2018

Super helpful thanks muchly!

@10ARK-StephenKie

This comment has been minimized.

Copy link

commented May 29, 2018

Many thanks, this really helped.

@herrvigg

This comment has been minimized.

Copy link

commented Jun 24, 2018

So many steps, it seems quite over complicated... Why don't you just do a git clone --bare + git push --mirror ?
All branches and tags are duplicated with this method, as explained on this github page.

https://help.github.com/articles/duplicating-a-repository/

Also, note the difference between a git clone --bare and git clone --mirror.

@adeelahmadkreditech

This comment has been minimized.

Copy link

commented Aug 13, 2018

@herrvigg

I tried your way and it works like a charm. everything is there in my new repo.

git clone --bare https://github.com/exampleuser/old-repository.git

cd old-repository.git

git push --mirror https://github.com/exampleuser/new-repository.git

  • 1 for simplicity. 👍
@Sritechops

This comment has been minimized.

Copy link

commented Aug 14, 2018

@herrvig. thank you , I wasted 30 mins and after seeing your comment I did it in 2 mins..

@xgenem

This comment has been minimized.

Copy link

commented Sep 9, 2018

This is helpful! Thank you!

@amitjain2405

This comment has been minimized.

Copy link

commented Nov 29, 2018

@prashathsenthil You have to run these commands as below

git clone --mirror <url_of_old_repo>
cd <name_of_old_repo>
git remote add new-origin <url_of_new_repo>
git push new-origin --mirror

This was helpful, thanks.

@elisboa

This comment has been minimized.

Copy link

commented Feb 8, 2019

Hi guys. You can use these parameters below, so you don't need to cd to the repo dir:

@elisboa

This comment has been minimized.

Copy link

commented Feb 8, 2019

Hi guys. You can use these parameters below, so you don't need to cd to the repo dir:

git remote add new-origin <url_of_new_repo> --git-dir <repo_dir>/.git --work-tree <repo_dir> git push new-origin --mirror --git-dir <repo_dir>/.git --work-tree <repo_dir>

@elisboa

This comment has been minimized.

Copy link

commented Feb 8, 2019

Hi guys. You can use these parameters below, so you don't need to cd to the repo dir:

git remote add new-origin <url_of_new_repo> --git-dir <repo_dir>/.git --work-tree <repo_dir> git push new-origin --mirror --git-dir <repo_dir>/.git --work-tree <repo_dir>

This might be useful when you are running a script that parses several repositories and you don't want to risk cd'ing to a dir that does not work as a repo dir.

@gdsotirov

This comment has been minimized.

Copy link

commented Feb 14, 2019

I was able to import the branches of my migrated with cvs2git old CVS repository following the information here. The key was to make local copy of remote branches with git checkout -b <branch> origin/<branch>, because apparently otherwise the branches are not imported by GitHub. Thanks!

@pkmishrakit

This comment has been minimized.

Copy link

commented Mar 8, 2019

Thanks for the useful info, however any idea to resolve the error "pre-receive hook declined", this is happening for many of my branches while running the above set of commands. Thanks in advance for your kind help.
screenshot 2019-03-08 at 2 54 00 pm

@schoolsplay

This comment has been minimized.

Copy link

commented Jun 11, 2019

Just moved multiple large repos from assembla to github without any problems thanks to your excellent guide.
Thanks for sharing the info :-)
And to the people who complain about the fact that it would be somehow over complicated, let me say this.
For something important as source code, keeping history, branches and all is way more important then "look at me with my cryptic one liner"
Some things are important enough to do "by hand" to keep track of every change you make. because you can not afford making mistakes

@progovoy

This comment has been minimized.

Copy link

commented Jun 19, 2019

Great and simple. This is the way to go! Thank you :)

@ChanseBradell

This comment has been minimized.

Copy link

commented Jul 1, 2019

@pkmishrakit That error generally means you don't have permission to push to the repo and need to check your permission settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.