Git push branch de um controle remoto para outro?

133

Eu tenho os seguintes controles remotos configurados:

$ git remote 
korg
rorg

E os seguintes ramos:

$ 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

Agora , desejo enviar todas as ramificações remotas korgpara o rorgcontrole remoto. Como faço isso?

De preferência, sem fazer uma ramificação local para cada primeiro, se isso for evitável.

Bjarke Freund-Hansen
fonte
Suponho que a resposta para este seja comparável à resposta para este: stackoverflow.com/questions/6922700/… .
Legolas

Respostas:

52

Um teste rápido que faz alguns repositórios temporários mostra que você pode construir um refspec que pode fazer isso:

$ 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

Origem / BRANCHNAME: refs / heads / BRANCHNAME

Verificando no meu rorgcontrole remoto:

pat@host /tmp/rorg (BARE:master)
$ git graph --all
* 5750bca (HEAD, master) c
| * 13fd55a (one) b
|/
* 822e0de a
patthoyts
fonte
5
Por que não git push rorg origin/one:one(sem refs/heads/) em vez disso?
Ali
2
@exalted porque com refs/heads/prefixo que você está empurrando ramificada remoto que não precisa ser checkouted em umone
ДМИТРИЙ МАЛИКОВ
@patthoyts Eu tentei o comando mencionado, ele diz tudo atualizado, mas eu tenho 10 ramos no remoto A e 6 ramos no remoto B, então você pode me dizer como posso mover os ramos deixados de fora?
precisa saber é o seguinte
219

Eu encontrei este:

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

E empurrou todos os meus ramos remotos do korg para o rorg (mesmo sem cópias locais dos ramos). Veja a saída abaixo:

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

E então você pode fazer o mesmo push para tagsrefs:

git push rorg 'refs/tags/*:refs/tags/*'
radistao
fonte
2
No novo suficiente (qual versão?) Do git, essa deve ser a resposta aceita. @ bjarke-freund-hansen você gostaria de alterar a resposta aceita se concordar com o benefício de futuros pesquisadores?
Jonah Graham
1
"Em uma versão suficientemente nova (qual versão?) Do git, esta deve ser a resposta aceita" como eu sei, isso deve funcionar para todas as versões públicas do git, porque esses curingas de assinatura e de push são comuns
radistao
3
Dá-me Everything up-to-dateno git 2.10.0 sem que nada aconteça, enquanto faz o mesmo em ramificações individuais.
user239558
6
Apenas pensei em chamar isso: este método parece criar uma ramificação real no controle remoto chamado HEAD. Mas isso pode ser excluído. git push rorg :HEAD
precisa
1
Quem não está familiarizado com a estrutura refs e querendo saber como empurrar as tags, você quer este comando: git push rorg refs/tags/*:refs/tags/*. Que é o mesmo que git push rorg --tags, mas é bom para entender o que essas coisas estão fazendo :)
Mark Stickley
14

Para complementar a resposta do patthoyt , aqui está um breve script de shell que empurra todos os ramos de um controle remoto para outro:

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

Para resumir, para cada ramificação remota no controle remoto de origem (excluindo ramificações "indicadoras" como HEAD), empurre essa referência para o controle remoto de destino. (O ${a//$SRC_REMOTE\/}bit retira o nome remoto da origem do nome do ramo, ou seja, origin/masterse torna master.)

blahdiblah
fonte
3
para aqueles de nós que precisam fazê-lo de uma só vez: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)
Jayen
3

Isso funciona no Zsh

git push rorg 'refs/remotes/korg/*:refs/heads/*'
zhudongfang
fonte
Lamentamos, mas a sua resposta foi idêntica à do radistao acima ( stackoverflow.com/a/21133502/235878 ), publicada em '14.
Patrick
0

Para qualquer script que sugiro que você execute, seria recomendável ocultar ou confirmar todas as suas alterações.

Eu precisava empurrar vários galhos de um controle remoto para outro. Essas respostas exigiram que as filiais locais existissem anteriormente

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

Apenas mude origin1 para o controle remoto de origem e origin2 para o controle remoto de destino. Copie isso para "remoteBranchCloner.sh" e chame-o usando "sh callBranchCloner.sh".

Pode haver uma maneira melhor , que não faça várias tentativas.

Se você usa meu código, provavelmente deseja usar o cache de credenciais, caso contrário , precisará digitar suas credenciais vezes no servidor.

Para janelas :

Nota: Este script é para linux . Se você o executar no "git bash", o script funcionará, mas você não poderá executá-lo no console nativo sem ter instalado algo especial.

git config [--global] credential.helper wincred

Para linux

git config [--global] credential.helper cache

Onde [--global] significa opcionalmente adicionar --global

Se você deseja definir o rastreamento remoto para todas as filiais para um novo controle remoto:

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

Armazenado como um arquivo .sh e executado com "sh filename.sh", todos os upstreams serão rastreados para rastrear 'remotename' remoto

csga5000
fonte
0

Como o HEADramo extra foi criado na resposta anterior , a maneira mais limpa de fazer isso é clonar em um repositório vazio e enviar todos os ramos para o controle remoto da seguinte maneira:

git clone --bare <from-repository>
cd <from-repo-dir>
git push --set-upstream <to-repository> --all
git push --set-upstream <to-repository> --tags
Kurt Vangraefschepe
fonte