Git push branch from one remote to another?
GitGit BranchGit PushGit RemoteGit Problem Overview
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.
Git Solutions
Solution 1 - Git
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/*'
Solution 2 - Git
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
Solution 3 - Git
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
.)
Solution 4 - Git
This works in Zsh
Notice the single quote is necessary to prevent unexpected parameter expansion in some cases.
git push rorg 'refs/remotes/korg/*:refs/heads/*'
Solution 5 - Git
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'
Solution 6 - Git
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