Git push branch from one remote to another?

50,848

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/*'
Share:
50,848
Bjarke Freund-Hansen
Author by

Bjarke Freund-Hansen

Updated on September 16, 2020

Comments

  • Bjarke Freund-Hansen
    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 the rorg remote. How do I do that?

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

  • Ali
    Ali almost 11 years
    Why not git push rorg origin/one:one (without refs/heads/) instead?
  • Jayen
    Jayen over 10 years
    for 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 a one
  • Jonah Graham
    Jonah Graham over 8 years
    In 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
    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
    user239558 about 7 years
    Gives me Everything up-to-date on git 2.10.0 with nothing happening, while doing the same on individual branches works.
  • radistao
    radistao about 7 years
    did you try with individual branch in such syntax: git push rorg refs/remotes/korg/branch_name:refs/heads/branch_name
  • Mark Stickley
    Mark Stickley about 7 years
    Just 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
    Mark Stickley about 7 years
    Anyone 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 as git push rorg --tags, but it's good to understand what these things are doing :)
  • radistao
    radistao about 7 years
    ths, i put it as an example too
  • keshav kowshik
    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
    Alpha about 5 years
    This approach gives "Everything up to date" in Windows, but if you execute from bash (even in Windows) it works as expected.
  • Pathogen David
    Pathogen David about 5 years
    If 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
    Patrick about 4 years
    Sorry I downvote it but your answer is identical as radistao above (stackoverflow.com/a/21133502/235878) which was posted in '14.
  • 0xC0000022L
    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
    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
    0xC0000022L over 3 years
    @Patrick very true, could have been pointed out ... or rather should have been.