De vez en cuando, obtendrá un conflicto cuando actualice/fusione sus ficheros desde el repositorio o cuando cambie su copia de trabajo a una URL diferente. Hay dos tipos de conflictos:
Un conflicto de fichero ocurre si dos (o más) desarrolladores han cambiado las mismas líneas de un fichero.
Un conflicto de árbol ocurre cuando un desarrollador mueve/renombra/elimina un fichero o una carpeta, que otro desarrollador también ha movido/renombrado/borrado, o quizás lo haya modificado.
Un conflicto de fichero ocurre cuando uno o más desarolladores han hecho cambios en las mismas líneas de un fichero. Dado que Subversion no sabe nada de su proyecto, delega la resolución de los conflictos en los desarrolladores. Cuando se le informa de un conficto, debería abrir el fichero en cuestión, y buscar líneas que empiecen con el texto <<<<<<<. El área conflictiva se marca así:
<<<<<<< nombre-del-fichero sus cambios ======= código fusionado del repositorio >>>>>>> revisión
Además, para cada fichero en conflicto Subversion deja tres ficheros adicionales en su directorio:
Este es su fichero tal y como estaba en su copia de trabajo antes de que actualizara su copia de trabajo - esto es, sin marcadores de conflicto. Este fichero tiene sus últimos cambios en él y nada más.
Este es el fichero que era la revisión BASE antes de que actualizara su copia de trabajo. Esto es, el fichero que obtuvo antes de empezar a hacer sus últimos cambios.
Este es el fichero que su cliente de Subversion acaba de recibir desde el servidor del que actualizó su copia de trabajo. Este fichero corresponde a la revisión HEAD del repositorio.
Puede o bien lanzar una herramienta externa de fusiones / editor de conflictos con el menú contextual → o bien utilizar otro editor manualmente para resolver el conflicto. Debe decidir cómo tiene que quedar el código, hacer los cambios necesarios, y grabar el fichero.
Después, ejecute el comando → y confirme sus modificaciones al repositorio. Tome nota de que el comando Resolver realmente no resuelve el conflicto. Simplemente elimina los ficheros filename.ext.mine y filename.ext.r*, dejándole confirmar sus cambios.
Si tiene conflictos con ficheros binarios, Subversion no intentará mezclar dichos ficheros por si mismo. El fichero local se mantendrá sin cambios (exactamente tal y como lo había cambiado usted) y obtendrá unos ficheros nombrefichero.ext.r*. Si desea descartar sus cambios y quedarse con la versión del repositorio, utilice el comando Revertir. Si desea mantener su versión y sobreescribir la versión del repositorio, utilice el comando Resuelto y luego confirme su versión.
Puede utilizar el comando Resuelto para múltiples ficheros si pulsa con el botón derecho en la carpeta padre y selecciona → Esto mostrará un diálogo con todos los ficheros en conflicto dentro de esa carpeta, y le permitirá seleccionar cuáles marcar como resueltos.
Un conflicto de árbol ocurre cuando un desarrollador mueve/renombra/elimina un fichero o una carpeta, que otro desarrollador también ha movido/renombrado/borrado, o quizás lo haya modificado. Hay diferentes situaciones que puede resultar en un conflicto de árbol, y todas ellas requiere pasos diferentes para resolver el conflicto.
Cuando se elimina un fichero de forma local en Subversion, el fichero también se elimina del sistema local de ficheros, por lo que incluso si es parte de un conflicto de árbol no se puede mostrar una sobreimpresión de conflicto y no puede hacer clic con el botón derecho sobre él para resolver el conflicto. En este caso, utilice el diálogo Comprobar modificaciones para acceder a la opción Editar conflictos.
TortoiseSVN puede ayudarle a encontrar el lugar correcto para fusionar los cambios, pero puede que necesite realizar un trabajo adicional para arreglar los conflictos. Recuerde que tras una actualización la BASE de trabajo siempre contendrá la revisión de cada ítem tal y como estaba en el repositorio en el momento de la actualización. Si revierte un cambio tras la actualización, se revierte a su estado del repositorio, no a como estaba cuando empezó a hacer sus propios cambios locales.
El desarrollador A modifica Foo.c y lo confirma en el repositorio
El desarrollador B al mismo tiempo ha movido Foo.c a Bar.c en su propia copia de trabajo, o simplemente ha borrado Foo.c o su carpeta padre.
Una actualización de la copia de trabajo del desarrollador B acaba con un conflicto de árbol:
Foo.c ha sido borrado de la copia de trabajo, pero está marcado como un conflicto de árbol.
Si el conflicto aparece después de un renombrado en vez de un borrado, entonces Bar.c está marcado como añadido, pero no contiene las modificaciones del desarrollador A.
El desarrollador B ahora tiene que elegir si mantiene los cambios realizados por el desarrollador A. En el caso de un renombrado, puede fusionar los cambios de Foo.c dentro del fichero renombrado Bar.c. Para simples borrados de ficheros o directorios puede elegir quedarse con los cambios del ítem del desarrollador A y descartar el borrado. O, si marca el conflicto como resuelto sin hacer nada más, estará descartando los cambios del desarrollador A.
El diálogo de editar conflictos ofrece la posibilidad de fusionar cambios si puede encontrar el fichero original del renombrado Bar.c. Dependiendo de dónde se haya realizado la actualización, puede que no sea posible encontrar el fichero de origen.
El desarrollador A mueve Foo.c a Bar.c y lo confirma en el repositorio.
El desarrollador B modifica Foo.c en su copia de trabajo.
O en el caso de mover una carpeta...
El desarrollador A mueve la carpeta padre FooFolder a BarFolder y lo confirma en el repositorio.
El desarrollador B modifica Foo.c en su copia de trabajo.
Una actualización de la copia de trabajo de B acaba con un conflicto de árbol. Para un conflicto simple de fichero:
Bar.c se añade a la copia de trabajo como un fichero normal.
Foo.c se marca como añadido (con historia) y tiene un conflicto de árbol.
Para un conflicto de carpeta:
BarFolder se añade a la copia de trabajo como una carpeta normal.
FooFolder se marca como añadida (con historia) y tiene un conflicto de árbol.
Foo.c se marca como modificado.
El desarrollador B tiene ahora que decidir si desea continuar con la reorganización del desarrollador A y fusionar sus cambios en los ficheros correspondientes de la nueva estructura, o simplemente revertir los cambios de A y mantener el fichero local.
Para fusionar sus cambios locales con la reorganización, el desarrollador B tiene que encontrar primero qué nombre de fichero tiene ahora el fichero en conflicto Foo.c que fue renombrado/movido en el repositorio. Esto puede hacerse utilizando el diálogo de registro. Luego debe fusionar los cambios a mano ya que no hay actualmente forma de automatizar o simplificar este proceso. Una vez que se hayan portado los cambios, la ruta en conflicto es redundante y puede borrarse. En este ccaso utilice el botón Eliminar en el diálogo de editar conflictos para limpiar y marcar el conflicto como resuelto.
Si el desarrollador B decide que los cambios de A eran erróneos deberá elegir el botón Mantener en el diálogo de editar conflictos. Esto marca el fichero o carpeta en conflicto como resuelto, pero los cambios del desarrollador A tendrán que eliminarse a mano. De nuevo el diálogo de registro ayuda a controlar lo que se ha movido.
El desarrollador A mueve Foo.c a Bar.c y lo confirma en el repositorio
El desarrollador B mueve Foo.c a Bix.c
Una actualización de la copia de trabajo del desarrollador B acaba con un conflicto de árbol:
Bix.c se marca como añadido con historia.
Bar.c se añade a la copia de trabajo con el estado 'normal'.
Foo.c se marca como borrado y tiene un conflicto de árbol.
Para resolver este conflicto, el desarrollador B tiene que averiguar qué nombre de fichero tiene ahora el fichero en conflicto Foo.c que fue renombrado/movido en el repositorio. Esto puede hacerse utilizando el diálogo de registro.
Luego el desarrollador B tiene que decidir qué nuevo nombre de fichero de Foo.c mantiene - el del desarrollador A o el renombrado que hizo él mismo.
Después de que el desarrollador B haya resuelto manualmente el conflicto, el conflicto de árbol debe marcarse como resuelto mediante el botón del diálogo de editar conflictos.
El desarrollador A, que está trabajando en el tronco, modifica Foo.c y lo confirma en el repositorio
El desarrollador B, que está trabajando en una rama, mueve Foo.c a Bar.c y lo confirma en el repositorio
Una fusión de los cambios en el tronco del desarrollador A con los cambios de la copia de trabajo de la rama del desarrollador B acaba con un conflicto de árbol:
Bar.c ya está en la copia de trabajo con estado 'normal'.
Foo.c se marca como faltante con un conflicto de árbol.
Para resolver este conflicto, el desarrollador B tiene que marcar el fichero como resuelto en el diálogo de edición de conflictos, lo que lo eliminará de la lista de conflictos. Luego tendrá que decidir si copia el fichero faltante Foo.c desde el repositorio a la copia de trabajo, si fusiona los cambios del desarrollador A hechos a Foo.c en el fichero renombrado Bar.c, o si desea ignorar los cambios marcando el conflicto como resuelto y no haciendo nada más.
Tenga en cuenta que si copia el fichero faltante desde el repositorio y luego marca como resuelto, su copia de eliminará de nuevo. Tiene que resolver el conflicto antes.
El desarrollador A, que está trabajando en el tronco, mueve Foo.c a Bar.c y lo confirma en el repositorio
El desarrollador B, que está trabajando en una rama, modifica el fichero Foo.c y lo confirma en el repositorio.
Hay un caso equivalente cuando se mueven carpetas, pero todavía no se detecta en Subversion 1.6...
El desarrollador A, que está trabajando en el tronco, mueve la carpeta padre FooFolder a BarFolder y lo confirma en el repositorio.
El desarrollador B, que está trabajando en un rama, modifica Foo.c en su copia de trabajo.
Una fusión de los cambios en el tronco del desarrollador A con los cambios de la copia de trabajo de la rama del desarrollador B acaba con un conflicto de árbol:
Bar.c se marca como añadido.
Foo.c se marca como modificado con un conflicto de árbol.
El desarrollador B tiene ahora que decidir si desea continuar con la reorganización del desarrollador A y fusionar sus cambios en los ficheros correspondientes de la nueva estructura, o simplemente revertir los cambios de A y mantener el fichero local.
Para fusionar sus cambios locales con la reorganización, el desarrollador B debe primero averiguar qué nombre de fichero tiene ahora el fichero en conflicto Foo.c que fue renombrado/movido en el repositorio. Esto se puede hacer utilizando el diálogo mostrar registro sobre el origen de la fusión. El editor de conflictos sólo muestra el registro para la copia de trabajo ya que no sabe qué ruta fue utilizada en la fusión, así que lo tendrá que averiguar por su cuenta. Luego se deben fusionar los cambios a mano ya que no hay actualmente forma de automatizar o simplificar este proceso. Una vez que los cambios se hayan portado, la ruta en conflicto es redundante y puede eliminarse. En este caso utilice el botón Eliminar en el diálogo de edición de conflictos para limpiar y marcar el conflicto como resuelto.
Si el desarrollador B decide que los cambios de A eran erróneos, deberá elegir el botón Mantener en el diálogo de editar conflictos. Esto marca el fichero o carpeta en conflicto como resuelto, pero los cambios del desarrollador A deberán eliminarse a mano. De nuevo el diálogo de registro sobre el origen de la fusión ayuda a averiguar qué se movió.
El desarrollador A, que está trabajando en el tronco, mueve Foo.c a Bar.c y lo confirma en el repositorio
El desarrollador B, que está trabajando en una rama, mueve Foo.c a Bix.c y lo confirma en el repositorio
Una fusión de los cambios en el tronco del desarrollador A con los cambios de la copia de trabajo de la rama del desarrollador B acaba con un conflicto de árbol:
Bix.c se marca con el estado normal (no modificado).
Bar.c se marca como añadido con historia.
Foo.c se marca como faltante con un conflicto de árbol.
Para resolver este conflicto, el desarrollador B tiene que averiguar qué nombre de fichero tiene ahora el fichero en conflicto Foo.c que fue renombrado/movido en el repositorio. Esto puede hacerse utilizando el diálogo de registro sobre el origen de la fusión. El editor de conflictos sólo muestra el registro de la copia de trabajo, dado que no conoce qué ruta se utilizó para la fusión, por lo que tendrá que averiguarlo por si mismo.
Luego el desarrollador B tiene que decidir qué nuevo nombre de fichero de Foo.c mantiene - el del desarrollador A o el renombrado que hizo él mismo.
Después de que el desarrollador B haya resuelto manualmente el conflicto, el conflicto de árbol debe marcarse como resuelto mediante el botón del diálogo de editar conflictos.