Actualizar ramas de Git desde master

676

Soy nuevo en Git, y ahora estoy en esta situación:

  • Tengo cuatro ramas (master, b1, b2 y b3).
  • Después de trabajar en b1-b3, me di cuenta de que tenía algo que cambiar en la rama maestra que debería estar en todas las demás ramas.
  • Cambié lo que necesitaba mastery ... aquí está mi problema:

¿Cómo actualizo todas las demás sucursales con mastercódigo de sucursal?

Ionuț Staicu
fuente
3
Encontré mi respuesta aquí: ¿Cómo fusionar archivos selectivos con git-merge?
wjandrea
59
Otra tarea simple que Git hizo difícil. Los desarrolladores de Git deben usar Stack Overflow como comentarios en su bucle SDLC. 300,000 personas deberían indicar que algo está muy mal con el flujo de trabajo de Git. Necesitan contratar a un experto en UX porque claramente no pueden hacerlo bien por sí mismos.
jww

Respuestas:

621

Tienes dos opciones:

El primero es una fusión, pero esto crea una confirmación adicional para la fusión.

Verifique cada sucursal:

git checkout b1

Luego fusionar:

git merge origin/master

Luego presione:

git push origin b1

Alternativamente, puedes hacer un rebase:

git fetch
git rebase origin/master
Chris Kooken
fuente
15
Me preocupa este enfoque. Cuando ejecuto git log --graph, el gráfico muestra que el maestro está realmente combinado con la rama del tema. ¿Esto causará algún problema a largo plazo? Pensé que la mejor práctica es siempre fusionar la rama del tema con el maestro. Por favor comenta.
Patrick
2
Esté atento
Hampus Ahlgren
22
Estás fusionando master en b1. ¿Por qué got push origin master... no tiene sentido? No estás cambiando la rama maestra. Creo que es un error con 119 votos a favor: /
Yves Lange el
22
No use el método de combinación, usar git rebase masteres la respuesta correcta
Weston Ganger
66
Para aquellos de nosotros que leemos más tarde, la edición del autor abordó la preocupación de @Kursion sobre el error tipográfico. Además, la segunda respuesta más votada a continuación dice básicamente lo mismo que esta respuesta, pero con un diagrama de la estructura de la rama y una advertencia de por qué no querría volver a redactar.
beyondtheteal
496

Básicamente tienes dos opciones:

  1. Te unes. Eso es realmente bastante simple y una operación perfectamente local:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    Esto deja la historia exactamente como sucedió: bifurcaste de master, hiciste cambios en todas las ramas y finalmente incorporaste los cambios de master en las tres ramas.

    gitpuede manejar esta situación realmente bien, está diseñado para fusiones que ocurren en todas las direcciones, al mismo tiempo Puede confiar en que podrá juntar todos los hilos correctamente. Simplemente no le importa si la b1fusión de ramas mastero las masterfusiones b1, la confirmación de fusión se ve igual que git. La única diferencia es, qué rama termina apuntando a esta confirmación de fusión.

  2. Usted rebase. Las personas con un SVN o un fondo similar encuentran esto más intuitivo. Los comandos son análogos al caso de fusión:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

    A la gente le gusta este enfoque porque conserva un historial lineal en todas las ramas. Sin embargo, esta historia lineal es una mentira, y debe saber que lo es. Considere este gráfico de compromiso:

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    La fusión da como resultado la verdadera historia:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    El rebase, sin embargo, te da esta historia:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    El punto es que los commits E', F'y G'nunca existieron realmente, y probablemente nunca hayan sido probados. Puede que ni siquiera compilen. En realidad, es bastante fácil crear confirmaciones sin sentido a través de un rebase, especialmente cuando los cambios masterson importantes para el desarrollo b1.

    La consecuencia de esto puede ser, que no se puede distinguir cuál de las tres confirmaciones E, Fy Gen realidad introdujo una regresión, disminuyendo el valor de git bisect.

    No estoy diciendo que no debas usar git rebase. Tiene sus usos. Pero siempre que lo use, debe ser consciente del hecho de que está mintiendo sobre la historia. Y al menos deberías compilar probar los nuevos commits.

cmaster - restablecer monica
fuente
Yo estaba fusionando otra rama fuente (no principal) y los pasos adicionales para añadir a este bonito respuesta fue actualizarla en mi repo local antes de la fusión (para tener el último código localmente): git checkout <source branch> git pull. Luego continuando con lo anterior: git checkout b1...
Rod
3
Como usuario de SVN desde hace mucho tiempo, prefiero la opción de combinación a la nueva versión: el uso de cualquier control de versión es muy, muy importante para mantener registros precisos de los cambios que realizó y por qué. Puedo ver el atractivo de la nueva versión para simplificar la historia aparente, pero luego debe regresar y agregar comentarios de confirmación de E ', F', G ', y preferiblemente agregar la nueva versión automáticamente a esos comentarios. De lo contrario, si el proceso de compilación / prueba / implementación de prueba se interrumpe en G ', debe averiguar por qué los cambios se realizaron sin información completa.
WillC
13
La historia es una mentira
piratemurray
Gracias, uso "git merge any-branch-name" para fusionar un código de rama a otra rama. A nivel local, puedo probar el código de la sucursal 1 mientras estoy en la sucursal 2
Priti
1
@blamb Los conflictos de fusión ocurren con ambos git mergey git rebase. No hay forma de evitarlos. git rebasetiene la ventaja de permitirle ocultar varias etapas de rebase (es decir, rebase la misma rama en varias confirmaciones diferentes en secuencia para reducir la cantidad de conflictos en cada etapa). Sin embargo, el mero hecho de que una nueva versión mienta sobre la historia hace que sea mucho más fácil joder bien en una nueva versión de varias etapas ... Es por eso que siempre prefiero la combinación, incluso cuando significa que necesito saturar la historia con varias confirmaciones de combinación. .
cmaster - reinstalar a monica el
238

git rebase masteres la forma correcta de hacer esto. Fusionar significaría que se crearía un commit para la fusión, mientras que rebase no.

Michael J. Gray
fuente
52
¿Qué pasa cuando ya ha empujado al origen? Si vuelve a redactar, volverá a escribir el historial de confirmación y esto entrará en conflicto con su rama remota. Creo que rebase solo debe usarse en un tirón o cuando no ha empujado a una rama remota.
Matt Smith
66
Si usted es el único que trabaja en la sucursal remota, puede hacer git push --force origin source para actualizar su sucursal remota con una sucursal local modificada. stackoverflow.com/questions/8939977/…
stormwild
77
reenfocar y fusionar ambos trabajos, rebase es mejor para sucursales privadas, ya que proporciona un gráfico de historial más limpio. esta respuesta es la mejor
Junchen Liu
55
Debe ser más claro acerca de la compensación entre la claridad (ideal para un solo usuario o equipo pequeño) o la verdad desordenada (para ramas de código de múltiples contribuyentes, necesarias para la mantenibilidad (en mi experiencia, YMMV)).
WillC
1
re "¿y si ya has presionado?" -> La regla de oro de git rebase es nunca usarlo en ramas públicas .
Trevor Boyd Smith
53

Si ha estado trabajando de vez en cuando en una sucursal, o han sucedido muchas cosas en otras sucursales mientras ha estado trabajando en algo, es mejor volver a armar su sucursal en maestra. Esto mantiene la historia ordenada y hace que las cosas sean mucho más fáciles de seguir.

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

Notas:

  • No rebajas las ramas en las que has colaborado con otros.
  • Debes volver a basar en la rama a la que te unirás, que no siempre será maestra.

Hay un capítulo sobre rebase en http://git-scm.com/book/ch3-6.html , y muchos otros recursos disponibles en la web.

Simon Bingham
fuente
Gracias por la solución simple
otro chico alto
18

@cmaster hizo la mejor respuesta elaborada. En breve:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

No debe reescribir el historial de la rama sino mantenerlos en estado real para futuras referencias. Mientras se fusiona para dominar, crea una confirmación adicional, pero eso es barato. Los compromisos no cuestan.

Luna azul
fuente
13

Para actualizar otras ramas como (copia de seguridad) con su copia de rama maestra. Puede seguirlo de cualquier manera (rebase o fusión) ...

  1. Realice un rebase (no se realizará ninguna confirmación adicional en la rama de respaldo).
  2. Fusionar ramas (habrá una confirmación adicional automáticamente en la rama de copia de seguridad).

    Nota: Rebase no es más que establecer una nueva base (una nueva copia)

git checkout backup
git merge master
git push

(Repita para otras ramas si hay alguna como backup2 y etc.,)

git checkout backup
git rebase master
git push

(Repita para otras ramas si hay alguna como backup2 y etc.,)

Sundar Gsv
fuente
9

Puede fusionar, o puede aplicar confirmaciones individuales a través de ramas mediante el uso de git cherry-pick .

Brian Agnew
fuente
1

Hay dos opciones para este problema.

1) git rebase

2) git merge

Solo difiere con los anteriores en caso de fusión, tendrá un compromiso adicional en la historia

1) rama de pago de git (b1, b2, b3)

2) git rebase origin / master (en caso de conflictos, resuelva localmente haciendo git rebase - continúe)

3) empuje git

Alternativamente, la opción git merge es una moda similar

1) git checkout "your_branch" (b1, b2, b3)

2) git merge master

3) empuje git

kris
fuente
1

para actualizar su sucursal desde el maestro:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
D_Oghli
fuente