2009-05-14 6 views
51

Tengo una rama principal en mi proyecto, que utilizo para obtener cambios de otras personas. A partir de eso, generalmente tengo varias ramas temáticas en las que estoy trabajando actualmente.Git: ¿Cómo volver a ordenar muchas ramas (con la misma confirmación base) a la vez?

Mi pregunta es: ¿hay alguna forma de que realice nuevos cambios en mi maestro y luego vuelva a establecer una base de TODAS mis ramas de tema sobre eso a la vez?

Esta es la situación:

 D--E topic1 
    /
A--B--C master 
     \ 
     F--G topic2 

y quiero lograr esto con un solo comando (H provenía de aguas arriba):

 
       D'--E' topic1 
      /
    A--B--C--H master 
       \ 
       F'--G' topic2 

Ahora, sé que puedo lograr esto mediante rebase topic1 y topic2 en master, e incluso podría escribir un script para automatizar esto. Pero, ¿y si tengo varias otras ramas, creo otras nuevas y elimino otras con frecuencia y recibo cambios ascendentes todo el tiempo?

Esta operación (varias rebases), cuando se realiza a mano, es cansadora y propensa a errores.

¿Hay alguna manera más fácil?

Gracias!

+1

[esta nueva pregunta] (http://stackoverflow.com/questions/5600659/rebasing- a-branch-includ ing-all-its-children/5600770 # 5600770) es probablemente un duplicado, pero no estoy seguro de que alguna vez se cierre como un duplicado de una pregunta anterior sin una respuesta real. – Cascabel

+1

Vea también [cómo volvería a basar una subhistoria completa - varias ramas, con algunos enlaces entre ellas como resultado de la combinación] (http://stackoverflow.com/a/9706495/94687). –

+0

'git rebase --onto' también debe mencionarse en caso de que' topic1' o 'topic2' tuvieran ramas secundarias https://coderwall.com/p/xzsr9g/rebasing-dependent-branches-with-git – quimnuss

Respuesta

17

Estoy bastante seguro de que no hay una manera de hacer esto automáticamente. Recuerda que "git rebase master" también puede devolverte al shell que necesita para resolver los conflictos de combinación, por lo que si quieres escribir un script para automatizar todo esto, debes tenerlo en cuenta.

Sin embargo, puede rastrear fácilmente qué ramas necesitan actualización. Hmm, para cualquier rama, "git rev-list branch..master" producirá salida si la rama no está actualizada wrt (es decir, simplemente se compromete encima de) master. Así que hay que recorrer todos los jefes locales, con excepción principal para producir un informe (nb "git show-rama" será aproximadamente de hacer esto):

git for-each-ref 'refs/heads/*' | \ 
    while read rev type ref; do 
    branch=$(expr "$ref" : 'refs/heads/\(.*\)') 
    revs=$(git rev-list $rev..master) 
    if [ -n "$revs" ]; then 
     echo $branch needs update 
     git diff --summary --shortstat -M -C -C $rev master 
    fi 
    done 

Así que si usted se sentía valiente, que podría sustituir a la "git diff "con algo así como" git checkout $ branch & & git rebase master "(o tal vez solo" git pull - rebase "si lo has configurado). Creo que tendrías que verificar la existencia de un directorio ".git/rebase-apply" o consultar el índice de archivos no compartidos ("git ls-files -u") para comprobar si nos han dejado esperando hacer una fusión

Por supuesto, si no hay ningún conflicto, entonces es fácil ... es producir algo que también funciona cuando no es fácil, que es el problema: p

Y esto no resuelve necesariamente lo que sucede si uno de sus ramas se basan en otra cosa ... es por eso que mencioné el uso de "git pull - rebase" en su lugar, porque eso se rebase de acuerdo con la configuración de la sucursal, no ciegamente desde el maestro. Aunque la detección no se basa en la configuración de la sucursal ... tal vez sería más fácil simplemente verificar cada sucursal y hacer "git pull" y dejar que la configuración de la sucursal maneje todo, incluso si se rebase o fusione.

+1

Gracias por la ayuda ! Supongo que esto es solo un problema más difícil de lo que pensé que era, así que seguiré con el reajuste manual. :) – malvim

+3

Utilizo 'git branch --no-fusionado' para listar las ramas que quiero traer al último máster. – rjmunro

+1

@rjmunro lindo, no sabía sobre esa bandera. Sin embargo, no creo que sea apropiado para el caso en que sus sucursales necesiten reajustarse en lugar de fusionarse. – araqnid

7

siempre puede escribir una carcasa de una sola línea como esta:

for branch in topic1 topic2 topic3;do git rebase master $branch;done 

Desde las ramas puntuales que le gustaría reajustar probablemente cambiar con el tiempo, este es un rápido y-dir^H^H^solución Hflexible :-)

+1

Consulte [esta respuesta] (http://stackoverflow.com/a/5632027/396967) a una pregunta relacionada para una versión "más inteligente", que determina automáticamente las ramas que contienen una confirmación básica particular. – kynan

0

he convertido esto en una escritura sólida, mantenida en my git-extensions repository:

$ git-urebaselocalbr --help 
Rebase all/the last committed N local branches (except for the current branch 
and master) to the updated upstream head. 
Usage: git-urebaselocalbr [--continue|--skip|--abort] [--branches "<branch1> ..."] [N] [-i|--interactive] [options] 
Cuestiones relacionadas