2012-02-02 6 views
18

Estoy trabajando en un proyecto de Rails a gran escala, y el equipo con el que estoy trabajando usa Github para administrar el proyecto. Si bien muchos cambios se trabajan localmente y luego se envían directamente a nuestra sucursal de desarrollo, creamos una rama cuando vamos a trabajar en un cambio muy grande. Cuando llegue el momento de fusionar esa rama nuevamente en desarrollo, a menudo trato de volver a desarrollar la base de mi rama de características antes de fusionar mi rama de características en desarrollo (para evitar sobrescribir el trabajo de otras personas). Encuentro que cuando hago esto, parece que me encuentro con los mismos conflictos de fusión dos veces. Me encuentro con una lista completa de conflictos mientras cambio de base, luego vuelvo a encontrar la misma lista de conflictos durante la fusión. ¿Debería volver a desarrollar la base de datos en mi rama de características antes de fusionar mi función en desarrollo, o debería fusionar mi función en el desarrollo?Cuando estoy usando Git, ¿debo volver a establecer la base de datos antes de fusionarme?

Digamos que mi rama de características se llama "new_feature". Mi proceso de fusión con la rama de "desarrollo" es la siguiente:

git checkout develop 

git pull (this is set up on our rig to always pull rebase) 

git checkout new_feature 

git rebase develop 

(lots of merge conflicts ensue) 

git checkout develop 

git merge -no-ff new_feature 

(same set of merge conflicts again) 

Es como si la línea de tiempo cambia de mi rebase porque mi nueva rama de la característica de especie de espejo desarrollar todo el camino de vuelta, y luego desarrollar conflictos con una copia de sí mismo.

+3

¿por qué 'git merge -no-ff'? Si acaba de actualizar new_feature para desarrollar, debería ser un avance rápido. – Useless

+0

Honestamente, no estoy seguro. Por un tiempo, tuvimos un tipo aquí que realmente conocía a Git, y él me dijo que debería hacerlo de esa manera por alguna razón que tuviera que ver con limpiar la línea de tiempo. Realmente no sé cuál fue el motivo. –

+1

Veo que puede hacer que la línea de tiempo sea confusa ... mmm. La rebase reemplaza todos los commits en 'new_feature' con cambios equivalentes aplicados a' develop' en lugar del punto de bifurcación original, lo que significa que obtendrá (copias de) commits antiguos, cuyos padres (entre el punto de bifurcación original y 'develop/HEAD') son más viejos que ellos. – Useless

Respuesta

29

Bien, esto es demasiado largo para un comentario ahora.

Parafraseando el manual (git help rebase)

Assume the following history exists and the current branch is "new_feature": 

       A---B---C new_feature 
       /
      D---E---F---G develop 


    From this point, the result of either of the following commands: 

     git rebase develop 
     git rebase develop new_feature 

    would be: 

         A'--B'--C' <new_feature 
         /
      D---E---F---G <develop 

Ahora, si tuviera conflictos, el estado real después de la primera ejecución rebase será

   A'--B'--C'--[local state] 
      / ^
D---E---F---G   new_feature 
      ^develop 

donde [local state] es la combinación de conflicto que todavía tienen arreglar. vez que haya resuelto los conflictos de fusión y añadido los archivos resueltos en el índice, se corre git rebase --continue: ahora su estado será

   A'--B'--C'--H <new_feature 
      /
D---E---F---G <develop 

Obviamente en este punto new_feature fusión de vuelta a desarrollar pueden ser reenviados rápido como tal :

   A'--B'--C'--H <new_feature <develop 
      /
D---E---F---G 

pero si no es que obtendrá este lugar

   A'--B'--C'--H <new_feature 
      /   \ 
D---E---F---G---------------I <develop 

Ahora cualquiera de estos se prefieren de una perspectiva de la línea de tiempo, no es obvio por qué cualquiera tendría un problema ... a menos que nunca hayas completado la rebase y resuelto los conflictos con H, pero creo que git se quejaría de eso.

+0

"pero si no es así, ¿conseguirás esto?" "no es" ¿qué? No entiendo cómo causar ninguno de estos escenarios. ¿Cuál fue la diferencia? – Umagon

+1

"_... se puede reenviar rápidamente ... pero si no es ..._". Si eliges no avanzar rápidamente la fusión, con '--no-ff', obtienes una combinación de fusión en lugar de solo mover el puntero de la rama, como se muestra en el diagrama. Sin embargo, si en primer lugar no comprende ninguno de los dos escenarios, probablemente deba hacer su propia pregunta u obtener más información sobre git, porque no puedo adivinar dónde la perdió. – Useless

4

Me parece que está utilizando rebase al revés, pero podría ser solo un fraseo confuso.

Reequilibré la rama de la característica en desarrollo y luego (en desarrollo) hago un git merge --ff-only feature.

+0

Estoy trabajando en la edición de mi publicación para mostrar el proceso, para ver si me estoy equivocando. –

+1

Como @Useless comentó, la combinación debe ser un avance rápido (prefiero forzarla usando --ff-only). Todo lo demás parece estar bien, aunque tu manera de expresarlo en palabras no es el estándar. Recomiendo leer http://progit.org/book/ – madth3

-1

Dado que especifica "gran escala" y "rebase" en la misma pregunta, le aconsejo que no haga eso. Use fusiones en su lugar.

El uso de --no-ff en fusiones es excelente con el fin de preservar el punto de ramificación original. Yo apoyo usarlo.

Cuestiones relacionadas