2012-04-12 19 views
8

Tuvimos un lanzamiento y el compromiso en cuestión (daf7110) estaba en la historia que se fusionó con el maestro. En este punto (85a13270), el maestro tiene las líneas de código que fueron agregadas por daf7110.¿Cómo puedo determinar por qué una fusión de git eliminó algunas líneas de código?

Cuando uno de nuestros desarrolladores fusionó master en su rama (dev-branch), las líneas de código desaparecieron. Nunca existieron en la historia del lado de la fusión del desarrollador. He verificado esto con:

git checkout c513d2 # <--last commit on dev-branch before the merge 
git log -S string_that_was_added -- lib/File/It/Was/In.pm 

Así:

  1. El código nunca existió en dev-rama antes de la fusión.
  2. Fue en maestro, añade, ya que "git merge-base c513d2 85a13270"

¿Cómo puedo obtener más detalles en cuanto a la razón por la lógica de combinación de git decidió el código no debe sobrevivir a la fusión? ¿O hay alguna otra razón por la cual mi compromiso no hubiera sobrevivido a esa fusión?

+4

pregunta estúpida, pero las líneas de código entran en conflicto con algunos cambios en la rama del desarrollador? Si es así, ¿sobrescribió los cambios con su propio compromiso? Eso parece más probable. – eykanal

+0

Lamentablemente, ese no es el caso. De hecho, puedo repetir la fusión reiniciando a c513d2, luego haciendo un "git merge 85a13270", y eso se fusiona sin conflictos, pero las líneas en cuestión desaparecen después de la fusión. –

+0

¿Se ha activado nuevamente? ¿Puedes reproducirlo en un pequeño repositorio autónomo solo con el archivo en cuestión y haciendo las mismas ediciones manualmente? –

Respuesta

11

No sé por qué razón esto podría pasar, pero puedo dar algunos consejos para la eliminación de fallas.

Primero, me aseguraré de que no tenga ninguna configuración extraña. Haga una nueva clonación de un repositorio que tenga ambas ramas, en una cuenta que no tenga ninguna configuración de Git. Intenta hacer una fusión. ¿Todavía sucede? De lo contrario, verifique su configuración, vea si hay algo extraño; en particular, sospecho de cualquier configuración nueva. Además, intente realizar la fusión con --no-rerere-autoupdate para ver si aún se eliminan las líneas en cuestión.

Después de eso, me gustaría empezar activando el máximo nivel de detalle para su combinación, y tratar de hacer la fusión de nuevo:

GIT_MERGE_VERBOSITY=5 git merge -v master 

esto le dará un poco más de información sobre las decisiones que el proceso de fusionar adoptada.

Si eso no termina diciéndole algo útil, también puede intentar ver si sucede con diferentes estrategias de combinación, o diferentes opciones a la estrategia de fusión recursiva predeterminada. Pruebe git merge -s resolve para probar una estrategia de fusión más sencilla pero más estúpida. ¿Todavía tienes el problema? ¿Qué tal probar diferentes opciones para la estrategia recursiva, como git merge -s recursive -X patience? Haga lo último con la verbosidad adicional activada, y vea si eso toma decisiones diferentes a la estrategia de fusión predeterminada.

Si eso no funciona, entonces es hora de intentar reducir esto manualmente a un caso de prueba mínimo. Primero, intentaría limitarme solo al archivo en cuestión. Asegúrese de estar trabajando en un repositorio desechable y use git filter-branch para eliminar todos los archivos, excepto el en cuestión del que faltan las líneas. Cuando haces eso, e intentas hacer la fusión nuevamente, ¿obtienes los mismos resultados? Si no, es posible que las líneas estén desapareciendo debido a que Git se confunde y piensa que se movieron a otro archivo cuando en realidad no lo hicieron.

Si aún puede reproducir el problema con solo un archivo, es hora de comenzar a recorrer el historial de revisión de cada rama, haciendo una combinación, hasta que el problema desaparezca. Por ejemplo, comenzando con la rama de desarrollo, retroceda aproximadamente hasta la mitad, intente hacer la fusión de nuevo, y vea si las líneas del maestro aún desaparecen. Si lo hacen, intente retroceder más. Si no, salta hacia delante a lo largo de la rama de desarrollo e inténtalo de nuevo. Una vez que haya encontrado la confirmación que introduce el problema en el desarrollo, pruebe lo mismo en el maestro, retrocediendo el compromiso en el que se está fusionando hasta que desaparezca el problema.

Ahora que ha retrocedido tanto como puede, intente volver a crear una versión simplificada de la historia antes de ese punto. Crea un nuevo repositorio de Git, comprueba la base de combinación de esos dos compromisos. Luego, comprueba los dos commits que rastreaste de nuevo en ramas separadas. ¿Puede fusionar esos sin problemas o depende de algún aspecto de la topología de fusión en el medio? Si es así, intente volver a crear la topología de combinación completa; crea solo las confirmaciones necesarias para hacer todas las fusiones en la historia. ¿Puede eso reproducir tu problema?

En este punto, debe tener la historia más simple posible para reproducir el problema, con solo un archivo que lo demuestre (o habrá encontrado algo interesante cuando no fue capaz de reducirlo más y reproducir el problema) Recomendaría publicar este repositorio públicamente para que podamos echarle un vistazo, si no hay nada delicado en ese archivo, o si hay, tratando de reducirlo aún más, editar cada compromiso para eliminar todo menos el líneas relevantes También debería poder reemplazar cada línea relevante con un valor de marcador de posición, dejándole un caso de prueba mínimo que no contenga ningún código real.

Todo lo anterior es una cantidad significativa de trabajo, pero con suerte encontrará algo interesante antes de completarlo todo, o puede saltearse y producir un caso de prueba mínimo sin pasar por todos los pasos intermedios. Una vez que tenga un caso de prueba más mínimo o los resultados de uno de los pasos anteriores, publíquelos y podremos verlos de cerca.

2

Me encontré con un problema similar, parece que se debió al hecho de que la línea de código en cuestión se introdujo primero mediante una confirmación, y luego se eliminó mediante una inversión, esa rama se fusionó con el maestro. Luego, esa línea se reintrodujo en una rama de desarrollo pero se eliminó sistemáticamente al fusionar la rama de desarrollo con el maestro. Supongo que, de alguna manera, Git realiza un seguimiento de la reversión y supone que esta línea no es necesaria y se eliminará.

+0

Estoy ejecutando una versión anterior de git 1.7.0.4 – Dominique

+0

git-merge solo se preocupa por los cambios relativos a la base de combinación, es decir, la confirmación más reciente alcanzable desde ambas ramas. Si se eliminó algo en la base de combinación y no se volvió a agregar en ninguna de las ramas más adelante, aún se eliminará después de la fusión. Esto se aplica a líneas únicas de código y archivos completos. – user2845840

Cuestiones relacionadas