Cómo mantener una rama git sincronizada con master

276

En el momento en que git está haciendo mi cabeza, no puedo encontrar la mejor solución para lo siguiente.

Hay dos ramas, una llamada master y otra llamada mobiledevicesupport . Quiero mantener el soporte de dispositivos móviles como una rama continua que se fusionará / sincronizará con la rama maestra siempre que el soporte de dispositivos móviles sea estable. Esto fusionaría los cambios de mobiledevicesupport a master pero también traería todos los cambios de master a mobiledevicesupport para que la rama pueda continuar trabajando y las características mejoradas o modificadas. Esto necesita trabajar con un repositorio central y múltiples desarrolladores.

Por favor, un ejemplo de flujos de trabajo similares que otras personas usan o simplemente díganme si esta idea es estúpida y debería considerar otras opciones. Por el momento, el flujo de trabajo parece sólido, pero no sé cómo puedo hacer que git funcione de esta manera.

Gracias, toda la ayuda muy apreciada.

Actualización 1: si tuviera que fusionar master en mobiledevicesupport y mobiledevice support en master, ¿obtengo commits replicados en ambas ramas? ¿O es lo suficientemente inteligente como para darse cuenta de que he extraído los últimos cambios de la rama A a la rama B y agrego el compromiso de fusión C a la rama B. Y he extraído los últimos cambios de la rama B a la rama A y agrego el compromiso de fusión D a la rama ¿UNA?

Iba a publicar una imagen pero no tengo suficiente reputación, así que supongo que la siguiente ilustración tendrá que funcionar. Dos ramas se ejecutan continuamente con fusiones que van en ambas direcciones a menudo. La clave de la que no estoy seguro es cómo git desarrollará los commits y si llenará cualquiera de las ramas con los commits de la otra rama en las fusiones o se mantendrá limpio. He usado rebase antes, pero parece terminar la rama y poner todos los commits en el maestro, o lo hice mal. Gracias por la ayuda hasta el momento.

master
A--B--C-----H--I--J--M--N
       \   /    \
mobile  \ /      \
D--E--F--G--------K--L
Sr. Ezequiel
fuente
1
Si, como yo, buscara cómo hacerlo con el cliente de GitHub : help.github.com/articles/merging-branches
cregox
1
Esta pregunta me salvó la vida durante siglos; Gracias por el gran esfuerzo en tomarse el tiempo para hacer esta maravillosa pregunta @Mr. EZEQUIEL
DJphy
En caso de que esté trabajando en una bifurcación, debe seguir help.github.com/articles/syncing-a-fork
koppor

Respuestas:

417

si solo haz

git checkout master
git pull
git checkout mobiledevicesupport
git merge master

mantener sincronizado el soporte de dispositivos móviles con el maestro

luego, cuando esté listo para poner el soporte de dispositivos móviles en master, primero combine en master como arriba, luego ...

git checkout master
git merge mobiledevicesupport
git push origin master

y eso es.

La suposición aquí es que mobilexxx es una rama temática con trabajo que aún no está listo para entrar en su rama principal. Por lo tanto, solo combínese en master cuando mobiledevicesupport esté en un buen lugar

concepto47
fuente
Esto me parece razonable, supongo que no estoy seguro de lo sucio que esto haría el historial de confirmaciones, actualizaré mi pregunta con un ejemplo de lo que creo que sucedería.
Sr. EZEKIEL
1
Tendrás bastantes "commits de fusión", esencialmente git tratando de resolver las diferencias entre tus ramas. si está preocupado por eso Y es el único que usa la rama, haga un "git rebase master" en lugar de un "git merge master" Y NO EMPUJE LOS COMPROMISOS A LA RAMA REMOTA. Si lo hace, se encontrará haciendo muchos empujones de fuerza (git push --force) al origen / soporte de dispositivos móviles porque (probablemente) siempre enviará un historial de confirmaciones que no coinciden con lo que la rama remota tiene. más detalles aquí git-scm.com/book/en/Git-Branching-Rebasing
concept47
Creo que esta es la respuesta correcta, suena exactamente como lo que quiero. Agregué una ilustración arriba para que quede un poco más claro, pero si lo que dices es cierto, entonces esto debería funcionar exactamente como quiero. Gracias.
Sr. EZEKIEL
2
Lea esto para comprender por qué este no es un consejo especialmente bueno: kentnguyen.com/development/visualized-git-practices-for-team/… . Eso fue escrito por el mantenedor de Git, por lo que probablemente sea justo decir que sabe de qué está hablando con respecto a este tema en particular.
Dan Molding
2
Esto hace que el historial de confirmación sea desordenado, vea mi respuesta a través de rebase
Gob00st
43

Siempre que desee obtener los cambios de maestro a su rama de trabajo, haga a git rebase <remote>/master. Si hay algún conflicto. resolverlos

Cuando su rama de trabajo esté lista, vuelva a redactar y luego haga git push <remote> HEAD:master. Esto actualizará la rama maestra en remoto (repositorio central).

euforia83
fuente
3
¿Cuáles son las ventajas y desventajas de hacerlo de esta manera en lugar de en la respuesta aceptada?
Hampus Ahlgren
33
Cuerdo hasta que pases 5 horas en rebase hell
IcedDante
21
Esto es cierto solo si su sucursal está en un repositorio privado. Nunca rebases algo que ha sido empujado río arriba. Esta es la razón: git-scm.com/book/en/v2/…
Kleag
3
El problema con el rebase es una reescritura de la historia es que los SHA del commit rebase se cambian y, por lo tanto, no puede confiar en la salida de (por ejemplo) git branch --contains <commit>.
jnns
13

El enfoque de concept47 es la forma correcta de hacerlo, pero le aconsejaría fusionarse con la opción --no-ff para mantener su historial de confirmaciones claro.

git checkout develop
git pull --rebase
git checkout NewFeatureBranch
git merge --no-ff master
IwishIcanFLighT
fuente
9

Sí, estoy de acuerdo con tu enfoque. Para combinar el soporte de dispositivos móviles en maestro, puede usar

git checkout master
git pull origin master //Get all latest commits of master branch
git merge mobiledevicesupport

Del mismo modo, también puede fusionar master en mobiledevicesupport.

P. Si la fusión cruzada es un problema o no.

R. Bueno, depende de las confirmaciones realizadas en la rama móvil * y la rama maestra desde la última vez que se sincronizaron. Tome este ejemplo: después de la última sincronización, las siguientes confirmaciones suceden a estas ramas

Master branch: A -> B -> C [where A,B,C are commits]
Mobile branch: D -> E

Ahora, suponga que commit B realizó algunos cambios en el archivo a.txt y commit D también realizó algunos cambios en a.txt. Echemos un vistazo al impacto de cada operación de fusión ahora,

git checkout master //Switches to master branch
git pull // Get the commits you don't have. May be your fellow workers have made them.
git merge mobiledevicesupport // It will try to add D and E in master branch.

Ahora, hay dos tipos de fusión posibles

  1. Combinación de avance rápido
  2. Verdadera fusión (requiere esfuerzo manual)

Git primero intentará hacer que FF se fusione y, si encuentra algún conflicto, git no puede resolverlo. Falla la fusión y le pide que se fusione. En este caso, se producirá una nueva confirmación que es responsable de resolver los conflictos en a.txt.

Entonces, la conclusión es que la fusión cruzada no es un problema y, en última instancia, debe hacerlo y eso es lo que significa la sincronización. Asegúrese de ensuciarse las manos al fusionar ramas antes de hacer algo en la producción.

sachinjain024
fuente
1
¿Entonces la fusión cruzada como esta no es un problema?
Sr. EZEKIEL
La fusión cruzada es lo que decimos sincronización y no es un problema a menos que los commits en ambas ramas no causen ningún conflicto. Por favor vea mi respuesta actualizada.
sachinjain024
3

La respuesta aceptada a través de git merge hará el trabajo pero deja una confusa hisotry commit, la forma correcta debe ser 'rebase' a través de los siguientes pasos (suponiendo que desee mantener su rama de características sincronizada con el desarrollo antes de hacer el empuje final antes de PR )

1 git fetchde su rama de características (asegúrese de que la rama de características en la que está trabajando esté actualizada hasta la fecha)

2 git rebase origin/develop

3 si surge algún conflicto, resuélvalos uno por uno

4 uso git rebase --continueuna vez que se aborden todos los conflictos

5 5 git push --force

Gob00st
fuente
1
Esto es difícil de leer y de entender. Actualice su respuesta y use el código de marcado apropiado para separar sus comentarios de los comandos.
not2qubit
2

Estás pensando en la dirección correcta. Fusionar master con mobiledevicesupport continuamente y fusionar mobiledevicesupport con master cuando mobiledevicesupport es estable. Cada desarrollador tendrá su propia sucursal y puede fusionarse desde y hacia el soporte de dispositivos maestros o móviles, dependiendo de su función.

faisal
fuente