git push all branches from one remote to another remote

Solution 1:

You may want to try cloning your upstream repo with --mirror option and then push to your new remote with --mirror option too

You'll have the following flow:

git clone <upstream-repo-url/repo.git> --mirror
cd <repo>
git remote add <your-remote-name> <your-remote-url/repo.git>
git push <your-remote-name> --mirror

⚠ Be really careful with the push --mirror as it will delete branches that are on your <your-remote-name>

Solution 2:

I just needed to copy one repository from Bitbucket to GitHub, these are the steps assuming your remote is called origin, all branches and tags will be copied:

git remote add neworigin url-to-new-remote
git push neworigin --tags "refs/remotes/origin/*:refs/heads/*"

Good thing about this is that files in your working copy won't be modified.

Solution 3:

One complete answer of cloning from one (bare) repository to another (bare) repository taking ALL branches, not just the checked out ones, is to clone a local bare repository as an intermediary. Then all branches are pulled as part of the clone and a git push --all will push them all. Example performed on Windows from github to gitlab:

  1. git clone --bare [email protected]:robe070/cookbooks.git
  2. cd cookbooks.git
  3. git remote add gitlab [email protected]:robe071/cookbookstest2.git
  4. git push --force --all gitlab
  5. git push --force --tags gitlab

Result: 25 branches pushed to gitlab

Note, git checkout is not required for all the branches and meaningless to a bare repo anyway.

Solution 4:

When you git push <REMOTE> --all or git push <REMOTE> --tags all branches and tags will push from your local history into the REMOTE. In this way, if you want push all of the branches and tags from a remote (i.e. origin) (not only your local history) to another remote (i.e. upstream) do the following procedure:

  1. Recieve all branches and tags from the origin and remove unmatched branches in your local history with the origin remote:
    • git fetch --prune
      
    • git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
      
    • git fetch --all
      
  2. Add new remote url:
    • git remote add upstream <the-url-path-of-a-remote.git>
      
  3. Now, your local is synchronized. Next, you can push all of the branches and tags to the new remote:
    • git push --all upstream
      git push --tags upstream
      

TL;DR

git fetch --prune
git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
git fetch --all
git remote add upstream <the-url-path-of-a-remote.git>
git push --all upstream
git push --tags upstream