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

jpjoyal 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

okram999 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

eirikb commented Oct 30, 2015

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

@niksumeiko

This comment has been minimized.

Copy link
Owner Author

niksumeiko 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

RoSk0 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

matm 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

prashathsenthil 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

vikas027 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

DowerPower 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

natsu90 commented Mar 22, 2016

Thanks @vikas027 @RoSk0 that works

@GeekInTheNorth

This comment has been minimized.

Copy link

GeekInTheNorth commented Apr 18, 2016

Thank you all, this worked a treat for me.

@ashiquehssn

This comment has been minimized.

Copy link

ashiquehssn 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

GPrathap commented May 18, 2016

Thanks guys it works

@bradhill99

This comment has been minimized.

Copy link

bradhill99 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

douglasdeodato commented Jul 26, 2016

very useful 👍

@tortal

This comment has been minimized.

Copy link

tortal 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

dorelljames 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

traveling-desi 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

faizan80 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

pablitoc 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

replay111 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

stocksnut commented Feb 21, 2017

Thank you @vikas027 that works good

@stalebbeik

This comment has been minimized.

Copy link

stalebbeik 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

shalinijeevanigi commented Jun 22, 2017

@vikas027, thanks for the clear and detailed steps.

@bennygenish

This comment has been minimized.

Copy link

bennygenish commented Jul 19, 2017

@vikas027, Works great. Thank you so much!

@igorrodygin

This comment has been minimized.

Copy link

igorrodygin commented Aug 26, 2017

@niksumeiko, Thank you!

@greenRoberto

This comment has been minimized.

Copy link

greenRoberto commented Sep 10, 2017

Thanks!!

@Dhaval2404

This comment has been minimized.

Copy link

Dhaval2404 commented Oct 10, 2017

Thank you so much..!!!

@danielpsf

This comment has been minimized.

Copy link

danielpsf commented Nov 9, 2017

Tks @RoSk0, worked like a charm 😉

@fthzkrtn

This comment has been minimized.

Copy link

fthzkrtn commented Dec 17, 2017

Thank you @RoSk0. Saved my day 👍

@BalmungSan

This comment has been minimized.

Copy link

BalmungSan commented Jan 25, 2018

Thanks

@kvsuresh

This comment has been minimized.

Copy link

kvsuresh commented Jan 30, 2018

thanks

@kvsuresh

This comment has been minimized.

Copy link

kvsuresh 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

jhhyj1010 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

Rktedlapu 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

pmacca 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

vinnyasa commented May 21, 2018

Thank you @niksumeiko this was super useful.

@lillypad

This comment has been minimized.

Copy link

lillypad commented May 27, 2018

Super helpful thanks muchly!

@10ARK-StephenKie

This comment has been minimized.

Copy link

10ARK-StephenKie commented May 29, 2018

Many thanks, this really helped.

@herrvigg

This comment has been minimized.

Copy link

herrvigg 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

adeelahmadkreditech 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

Sritechops 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

xgenem commented Sep 9, 2018

This is helpful! Thank you!

@amitjain2405

This comment has been minimized.

Copy link

amitjain2405 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

elisboa 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

elisboa 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

elisboa 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

gdsotirov 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

pkmishrakit 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

schoolsplay 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

progovoy commented Jun 19, 2019

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

@ChanseBradell

This comment has been minimized.

Copy link

ChanseBradell 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.

@liyongjun1

This comment has been minimized.

Copy link

liyongjun1 commented Sep 4, 2019

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 

@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

Thanks very much, I do it in this way , migrate all the branches in the repository from gerrit to gitlab successfuuly.

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Sep 26, 2019

image

i transferred from repo to another smoothly using the above commands.
But old branches are treated as new branches instead of being the exact copy of old branches.Thus its popping for pull request for all the branches.
Help me out

@niksumeiko

This comment has been minimized.

Copy link
Owner Author

niksumeiko commented Sep 26, 2019

@ravindrabhandarkar007, your branches are new, because they were migrated from an old repository and pushed to a new repository along with the rest. If you keep working on your main branches, these won't popup for pull request anymore.

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Sep 26, 2019

@niksumeiko

This comment has been minimized.

Copy link
Owner Author

niksumeiko commented Sep 26, 2019

When you migrate, you push everything from your local to a new repository (new "remote" in git terms). Old branches are considered new by a new remote because they were pushed for a first time.

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Sep 27, 2019

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Sep 27, 2019

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Sep 30, 2019

@liyongjun1

This comment has been minimized.

Copy link

liyongjun1 commented Sep 30, 2019

waiting for your reply On Fri, Sep 27, 2019 at 12:00 PM ravindra bhandarkar < ravindrabhandarkar007@gmail.com> wrote:

Can we fork it? is it a good practice? is there any other way? On Fri, Sep 27, 2019 at 11:49 AM ravindra bhandarkar < @.> wrote: > cant we prevent that scenario. cant we prevent it from happening? > I want them to be treated as old branches only.help me out? > > On Thu, Sep 26, 2019 at 1:35 PM Nik Sumeiko @.> > wrote: > >> When you migrate, you push everything from your local to a new >> repository (new "remote" in git terms). Old branches are considered new by >> a new remote because they were pushed for a first time. >> >> — >> You are receiving this because you were mentioned. >> Reply to this email directly, view it on GitHub >> https://gist.github.com/8972566?email_source=notifications&email_token=ALIO4IDZPNVQONIOYJYUJ4TQLRUOBA5CNFSM4HW7NI3KYY3PNVWWK3TUL52HS4DFVNDWS43UINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAFZNRU#gistcomment-3037978, >> or mute the thread >> https://github.com/notifications/unsubscribe-auth/ALIO4IENPGLSBY2DMW6NOKDQLRUOBANCNFSM4HW7NI3A >> . >> >

if you want to migrate the reponsitory. you must use --bare or --mirror option to clone it. then push it to the new remote reponsitory. Then all the branches will be migrate to the new repnsitory.

@niksumeiko

This comment has been minimized.

Copy link
Owner Author

niksumeiko commented Sep 30, 2019

Doesn't matter how we migrate, as soon as we push old branches to a new remote they will be considered as new once and Github will offer creating pull requests out them. But this Github notification is private to an author, so no one else sees them. As well, they will disappear when you keep working/pushing to your main branches within time. @ravindrabhandarkar007, why are you worrying?

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Sep 30, 2019

@ganginenivenu

This comment has been minimized.

Copy link

ganginenivenu commented Oct 18, 2019

git push new-origin --mirror

When i run command in Git bash, It is giving error you are exceeded the Git hub limit.
Git supports 100 MB while pushing the commits/Repo but my cloned existing Repo size is 350 MB.
How can we achieve this?

Steps executed:

  1. I have Cloned one repository from Gitlab eg: Repo1
  2. cd " Repo1"
  3. git add origin "Repo2"(which is created in github not gitlab)
  4. git push new-origin(Repo2) --mirror

Above mentioned error occurs and i could't push the cloned Repo1 to new Repo2 which is created in git hub.

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Oct 18, 2019

@ganginenivenu

This comment has been minimized.

Copy link

ganginenivenu commented Oct 18, 2019

github error

@ganginenivenu

This comment has been minimized.

Copy link

ganginenivenu commented Oct 18, 2019

git erro

@ravindrabhandarkar007

This comment has been minimized.

Copy link

ravindrabhandarkar007 commented Oct 21, 2019

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.