Git push branch from one remote to another?
Solution 1
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 2
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 3
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
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/*'
Bjarke Freund-Hansen
Updated on September 16, 2020Comments
-
Bjarke Freund-Hansen over 3 years
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 therorg
remote. How do I do that?Preferably without making a local branch for each first, if that is avoidable.
-
Legolas over 12 yearsI'm guessing the answer to this one is comparable to the answer to this one: stackoverflow.com/questions/6922700/….
-
-
Ali almost 11 yearsWhy not
git push rorg origin/one:one
(withoutrefs/heads/
) instead? -
Jayen over 10 yearsfor those of us that need to do it in one push:
git push -u $DST_REMOTE $(for a in $(git branch --list --remote "$SRC_REMOTE/*" | grep -v --regexp='->'); do echo "$a:refs/heads/${a//$SRC_REMOTE\/}"; done)
-
ДМИТРИЙ МАЛИКОВ almost 10 years@exalted because with
refs/heads/
prefix you're pushing remote branched that don't need to be checkouted into aone
-
Jonah Graham over 8 yearsIn new enough (what version?) of git, this should be the accepted answer. @bjarke-freund-hansen would you like to change the accepted answer if you agree for the benefit of future searchers?
-
radistao over 8 years"In new enough (what version?) of git, this should be the accepted answer" as i know, this should work for every public git version, because those push signature and references wildcards are common
-
user239558 about 7 yearsGives me
Everything up-to-date
on git 2.10.0 with nothing happening, while doing the same on individual branches works. -
radistao about 7 yearsdid you try with individual branch in such syntax:
git push rorg refs/remotes/korg/branch_name:refs/heads/branch_name
-
Mark Stickley about 7 yearsJust thought I should call this out: this method seems to create an actual branch on the remote called
HEAD
. But that can be deleted.git push rorg :HEAD
-
Mark Stickley about 7 yearsAnyone not familiar with the refs structure and wondering how to push the tags, you want this command:
git push rorg refs/tags/*:refs/tags/*
. Which is the same asgit push rorg --tags
, but it's good to understand what these things are doing :) -
radistao about 7 yearsths, i put it as an example too
-
keshav kowshik over 6 years@patthoyts I tried the mentioned command it says everything up to date, But I have 10 branches in remote A and 6 branches in remote B so can you please tell me how can I move the left out branches?
-
Alpha about 5 yearsThis approach gives "Everything up to date" in Windows, but if you execute from bash (even in Windows) it works as expected.
-
Pathogen David about 5 yearsIf you're running these commands from a Windows command prompt (as opposed to Git Bash or something similar), you need to use double quotes instead of single quotes.
-
Patrick about 4 yearsSorry I downvote it but your answer is identical as radistao above (stackoverflow.com/a/21133502/235878) which was posted in '14.
-
0xC0000022L over 3 years@Patrick you are missing the context - and a very important one, IMO - that the answer you mention was indeed written in 2014, but lacked the single-quotes until an edit about 1 year prior to your comment. So at the time this answer was written it was actually different in a rather relevant way.
-
Patrick over 3 years@0xC0000022L thanks for bringing this to my attention. I can see how parameter expansion might unintentionally affect the result. In my opinion though, if this answer was to highlight the missing single quote, it’d be better to call it out explicitly rather than left to the readers to do the detective work... in any case, I think it’s fair to restore the down vote as it’s indeed a better answer in ‘17.
-
0xC0000022L over 3 years@Patrick very true, could have been pointed out ... or rather should have been.