Question

I have the following remotes set up:

$ git remote 
korg
rorg

And the following branches:

$ git branch -a
* (no branch)
  remotes/korg/gingerbread
  remotes/korg/gingerbread-release
  remotes/korg/honeycomb
  remotes/korg/honeycomb-mr1-release
  remotes/korg/master
  remotes/m/android-2.3.3_r1 -> refs/tags/android-2.3.3_r1a
  remotes/m/gingerbread -> korg/gingerbread

Now I wish to push all the remote branches from korg to the rorg remote. How do I do that?

Preferably without making a local branch for each first, if that is avoidable.

Was it helpful?

Solution

A quick test making some temporary repositories shows you can construct a refspec that can do this:

$ git push rorg origin/one:refs/heads/one
Counting objects: 5, done.
Writing objects: 100% (3/3), 240 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To /tmp/rorg
 * [new branch]      origin/one -> one

So origin/BRANCHNAME:refs/heads/BRANCHNAME

Checking in my rorg remote:

pat@host /tmp/rorg (BARE:master)
$ git graph --all
* 5750bca (HEAD, master) c
| * 13fd55a (one) b
|/
* 822e0de a

OTHER TIPS

I've found this one:

git push rorg 'refs/remotes/korg/*:refs/heads/*'

And it pushed all my remote branches from korg to rorg (even without local copies of the branches). See the output below:

Counting objects: 293, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (67/67), done.
Writing objects: 100% (176/176), 48.32 KiB, done.
Total 176 (delta 105), reused 168 (delta 97)
remote: Resolving deltas:  11% (12/105)
To <<MY_REPOSITORY_URL>>
 * [new branch]      korg/gingerbread-> gingerbread
 * [new branch]      korg/gingerbread-release -> gingerbread-release
 * [new branch]      korg/honeycomb-> honeycomb
 * [new branch]      korg/HEAD -> HEAD
 * [new branch]      korg/honeycomb-mr1-release-> honeycomb-mr1-release
 * [new branch]      korg/master -> master

And then you can make the same push for tags refs:

git push rorg 'refs/tags/*:refs/tags/*'

To complement patthoyt's answer, here's a short shell script that pushes all the branches from one remote to another:

SRC_REMOTE=korg
DST_REMOTE=rorg
for a in $(git branch --list --remote "$SRC_REMOTE/*" | grep -v --regexp='->')
  do git push "$DST_REMOTE" "$a:refs/heads/${a//$SRC_REMOTE\/}"
done

To summarize, for each remote branch on the source remote (excluding "pointer" branches like HEAD), push that ref to the destination remote. (The ${a//$SRC_REMOTE\/} bit strips the source remote name from the branch name, i.e., origin/master becomes master.)

This works in Zsh

git push rorg 'refs/remotes/korg/*:refs/heads/*'

For any script I sugges you run, it would be wise to stash or commit all your changes.

I needed to push several branches from one remote to another. These answers required that the local branches previously existed

SRC_R=origin1
DEST_R=origin2
for cbranch in $(git branch -r | grep $SRC_R | cut -d '/' -f2,3,4,5 | cut -d ' ' -f1)
do
    git checkout $cbranch
    git push $DEST_R $cbranch
done

Just change origin1 to the source remote, and origin2 to the destination remote. Copy this into "remoteBranchCloner.sh" and call it using "sh callBranchCloner.sh".

There may be a better way, that doesn't do several pushes.

If you use my code you probably want to use credential caching, otherwise you have to type your credentials serveral times.

For windows:

Note: This script is for linux. If you run it in "git bash" the script will work, but you can't run it from the native console without having installed something special.

git config [--global] credential.helper wincred

For linux

git config [--global] credential.helper cache

Where [--global] means optionally add --global

If you would like to set remote tracking for all branches to a new remote:

DEST_R=remotename
for cbranch in `git branch`
do
    git checkout $cbranch
    git branch -u guru/$cbranch
done

Stored as a .sh file and ran with "sh filename.sh" will set all upstreams to track remote 'remotename'

Due to the extra HEAD branch being created in the previous answer, the cleanest way I found to do this is to clone into a bare repository and then push all branches to the remote as follows:

git clone --bare <from-repository>
cd <from-repo-dir>
git push --set-upstream <to-repository> --all
git push --set-upstream <to-repository> --tags
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top