2012-05-25 21 views
17

He estado tratando de entender a los modelos de git branching. He estado buscando en http://nvie.com/posts/a-successful-git-branching-model/ algunas ideas y, viniendo de Subversion, una cosa que realmente estaba esperando era hacer un cambio en un solo lugar y fusionarlo con todas las sucursales que lo necesitaban. En Subversion, terminamos haciendo mucha copia de código.Git fusionando hotfix en múltiples ramas

Sin embargo, todavía no entiendo esto por completo. Este es un tipo de flujo de trabajo estándar que tengo y siempre surgirán conflictos.

# create new version branch 
git checkout master 
git checkout -b v3 
vim pom.xml # change branch version to "3.1-SNAPSHOT" 
git commit -a 
git checkout master 
vim pom.xml # change master version to "4.0-SNAPSHOT" 
git commit -a 

Así que el maestro está en 4.0-SNAPSHOT y la rama está en 3.1-SNAPSHOT.

No quiero crear una revisión en la rama y moverla a la línea externa.

git checkout v3 
git checkout -b hotfix 
vim file.txt # make a bugfix change 
git commit -a 
git checkout v3 
git merge hotfix # this works fine 
git checkout master 
git merge hotfix # this has a conflict since both branches have changed the version 

Entiendo por qué está sucediendo y tiene sentido. ¿Hay una mejor manera de hacer esto?

leí sobre cereza-escoge, que Probé y hace el trabajo:

git checkout v3 
git cherry-pick a518b0b75eaf28868 
git checkout master 
git cherry-pick a518b0b75eaf28868 

Sin embargo, eso no parece la forma "correcta" para manejar esto. ¿Alguna sugerencia?

Respuesta

11

Realmente, su la respuesta depende de si desea que sus árboles se basen en el mismo historial ... Por ejemplo, 4.0 se basa en el último 3.X + todos los cambios en 4.0 ...

Personalmente, no lo hago Lo recomiendo una vez que decida comenzar una nueva rama (s) para una nueva versión (s). En un momento dado, el software está tomando una dirección diferente, por lo que sus ramas también deberían hacerlo.

Esto deja git cherry-pick como su solución ideal. Haga el cambio en la rama que tenga más sentido, y luego selecciónelo con las versiones anteriores. Esto es lo mismo que si hubiera revisado la rama anterior y manualmente aplicó el mismo cambio, e hizo una nueva confirmación. Lo mantiene limpio y al grano.

Git fusionar o rebase van a tratar de integrar la historia ramas juntas, cada una a su manera, que sospecho que no desea cuando backporting correcciones de errores, etc ...

+0

Estoy de acuerdo (aunque creo que la respuesta de @ellotheth puede ser más elegante dependiendo de las circunstancias). De acuerdo con la filosofía [de ramificación] de git (http://gitster.livejournal.com/42247.html) realmente es diciendo que _este commit_ es lo único que pertenece a todas las ramas. Por lo tanto, es lo que "dice" eso. –

+0

Gracias, creo que tiene sentido. Viniendo de Subversion, y lo doloroso que era a veces para nosotros aplicar soluciones al tronco y las ramas (básicamente haciendo la corrección dos veces), había pensado mentalmente que podía unir ramas de características en cualquier lugar que quisiera. Cuando eso no funcionó como esperaba, me sentí un poco decepcionado. "cherry-pick" tiene mucho sentido. Solo necesito llegar a un proceso que sea fácil de entender para todos los desarrolladores y creo que esto puede quedar bastante claro. –

1

En el caso, que están trabajando en la rama "4.0" y tienen que hacer un arreglo en "3.1", es posible que rebase "4.0" después de confirmar "3.1":

git checkout 4.0 # you are on the feature brnach 4.0 
git stash # save current work so you can check out other branch 
git checkout 3.1  
git commit -a -m "bug fix" # do editing and commit 
git checkout "4.0" 
git stash apply # get back your changes 
git rebase "3.1" # change 4.1 so it branches of the current head of "3.1" 
+3

Me gustaría comentar que si bien esto es posible, elimina la capacidad de confiar en las etiquetas, presionar o compartir eficientemente el código 4.0. Rebase es genial, personalmente, pero no tan bueno cuando ya has empujado. – gahooa

18

si se quería obtener súper técnica al respecto, podría crear la revisión de un ancestro común:

git merge-base v3 master 
git checkout -b hotfix <whatever you got from merge-base> 
# make your fix 
git checkout v3 && git merge --no-ff hotfix 
git checkout master && git merge --no-ff hotfix 

     v3--------v3 (hotfixed) 
    /  /
ancestor----hotfix 
     \   \ 
     master----master (hotfixed) 

la bandera --no-ff mantiene la etiqueta hotfix rama en la punta de revisión, en lugar de tirar de la etiqueta para v3 o master.

Personalmente, creo que es exagerado. Me gustaría ir con gahooa: hacer la revisión en la sucursal que tenga sentido, luego fusionarla o seleccionarla según la forma en que desee que las ramas se relacionen entre sí.

+3

+1 para 'merge-base',' --no-ff' y todos los buenos consejos. 'cherry-pick' crea una nueva confirmación: mismo diff, mensaje de registro, marca de tiempo, pero diferente hash. Si la historia clara es importante, no creo que la combinación de bases sea una exageración. La selección de cereza funcionará para casos simples, pero ten cuidado con cosas como esta: http://news.ycombinator.com/item?id=3947950 –

+0

Aprendimos mucho de tu respuesta, ¡gracias! –

0

He estado luchando con esta pregunta, también, y creo que si estás dispuesto a cambiar tu estrategia de control de versiones un poco (es decir, salga de las versiones -SNAPSHOT que Maven recomienda), esto podría resolverse usando una versión fija (como SNAPSHOT o 0.0.0-SNAPSHOT) en el maestro (o cualquiera que sea su rama de desarrollo). (El sufijo SNAPSHOT es importante, si está usando Maven, ya que Maven trata los artefactos versionados con SNAPSHOT de manera diferente que otros.)

De hecho, creo que querría establecer una política de cambio de número de versión únicamente. en su rama de producción (aquella desde la que crea las versiones) o en las ramas que solo tienen fines de publicación (por ejemplo, cambiar los números de versión) y que nunca intenta fusionar de nuevo a la rama de desarrollo.

No he usado esta estrategia aún, pero solo estaba pensando en ello, y creo que voy a empezar a probarlo.