Git empuje rama de un control remoto a otro?


133

Tengo los siguientes controles remotos configurados:

$ git remote 
korg
rorg

Y las siguientes ramas:

$ 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

Ahora deseo empujar todas las ramas remotas desde korgel rorgcontrol remoto. ¿Cómo puedo hacer eso?

Preferiblemente sin hacer una rama local para cada primero, si eso es evitable.


Supongo que la respuesta a esta es comparable a la respuesta a esta: stackoverflow.com/questions/6922700/… .
Legolas

Respuestas:


52

Una prueba rápida que hace algunos repositorios temporales muestra que puede construir una especificación de referencia que puede hacer esto:

$ 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

Entonces origen / BRANCHNAME: referencias / cabezas / BRANCHNAME

Comprobando en mi rorgcontrol remoto:

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

55
¿Por qué no git push rorg origin/one:one(sin refs/heads/) en su lugar?
Ali

2
@exaltado porque con el refs/heads/prefijo está empujando una ramificación remota que no necesita ser one
registrada

@patthoyts Probé el comando mencionado, dice que todo está actualizado, pero tengo 10 ramas en el control remoto A y 6 ramas en el control remoto B, ¿pueden decirme cómo puedo mover las ramas que quedan?
Keshav1234

219

He encontrado este:

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

Y empujó todas mis ramas remotas de korg a rorg (incluso sin copias locales de las ramas). Vea la salida a continuación:

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

Y luego puedes hacer el mismo impulso para los tagsárbitros:

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

2
En lo suficientemente nuevo (¿qué versión?) De git, esta debería ser la respuesta aceptada. @ bjarke-freund-hansen ¿le gustaría cambiar la respuesta aceptada si acepta el beneficio de los futuros buscadores?
Jonah Graham el

1
"En lo suficientemente nueva (? Qué versión) del GIT, esto debería ser la respuesta aceptada" que yo sepa, esto debería funcionar para todas las versiones Git pública, porque esos empuje de firma y referencias comodines son comunes
radistao

3
Me da Everything up-to-dateen git 2.10.0 sin que pase nada, mientras que hacer lo mismo en ramas individuales funciona.
user239558

66
Solo pensé que debería llamarlo: este método parece crear una rama real en el control remoto llamado HEAD. Pero eso puede ser eliminado. git push rorg :HEAD
Mark Stickley

1
Cualquiera que no esté familiarizado con la estructura de árbitros y preguntándose cómo empujar las etiquetas, desea que este comando: git push rorg refs/tags/*:refs/tags/*. Lo que es lo mismo git push rorg --tags, pero es bueno entender lo que están haciendo estas cosas :)
Mark Stickley

14

Para complementar la respuesta de patthoyt , aquí hay un breve script de shell que empuja todas las ramas de un control remoto a otro:

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 rama remota en la fuente remota (excluyendo las ramas "puntero" como HEAD), empuje esa referencia al control remoto de destino. (El ${a//$SRC_REMOTE\/}bit quita el nombre remoto de origen del nombre de la rama, es decir, se origin/masterconvierte en master).


3
para aquellos de nosotros que necesitamos hacerlo de una 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


0

Para cualquier script que sugiera que ejecute, sería aconsejable guardar o confirmar todos los cambios.

Necesitaba empujar varias ramas de un control remoto a otro. Estas respuestas requerían que las sucursales locales existieran previamente

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

Simplemente cambie origin1 al control remoto de origen y origin2 al control remoto de destino. Copie esto en "remoteBranchCloner.sh" y llámelo usando "sh callBranchCloner.sh".

Puede haber una mejor manera, que no haga varios empujones.

Si usa mi código, probablemente quiera usar el almacenamiento en caché de credenciales, de lo contrario, debe escribir sus credenciales varias veces.

Para ventanas :

Nota: Este script es para Linux . Si lo ejecuta en "git bash", el script funcionará, pero no puede ejecutarlo desde la consola nativa sin haber instalado algo especial.

git config [--global] credential.helper wincred

Para linux

git config [--global] credential.helper cache

Donde [--global] significa opcionalmente agregar --global

Si desea configurar el seguimiento remoto de todas las sucursales a un nuevo control remoto:

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

Almacenado como un archivo .sh y ejecutado con "sh filename.sh" configurará todas las secuencias ascendentes para rastrear 'remotename' remoto


0

Debido a la HEADrama adicional que se creó en la respuesta anterior , la forma más limpia que encontré para hacer esto es clonar en un repositorio desnudo y luego empujar todas las ramas al control remoto de la siguiente manera:

git clone --bare <from-repository>
cd <from-repo-dir>
git push --set-upstream <to-repository> --all
git push --set-upstream <to-repository> --tags
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.