Merges un poco más inteligentes para C#

Las operaciones de merge son muy comunes en los sistemas de control de versiones distribuidos, y si hay muchos cambios a nivel de pocos ficheros (equipos trabajando en una misma funcionalidad) podemos tener muchos conflictos. Para ayudar a mejorar la productividad en estas operaciones ayer hemos anunciado la disponibilidad a todo el público de la beta de SemanticMerge.

La idea es simplificar la resolución del conflicto entendiendo el código, resolviendo de manera automática aquellos en los que sea posible y permitir al usuario, de manera sencilla, encargarse de los conflictos restantes. En este artículo veremos de un vistazo la herramienta sus características, los casos que cubrimos y cómo la hemos desarrollado.

Una interfaz sencilla

La herramienta, formada básicamente por un panel donde se muestran los conflictos y diferencias, y un visor de código, permite por una parte resolver conflictos, y por otra ver en detalle los cambios sucedidos en cada fichero respecto a la base.

Para ayudar al usuario, cada conflicto tiene, en la cabecera, un campo identificado por una letra y un color por cada cambio que lleven al conflicto, en el ejemplo, un cambio concurrente en un método.

Semantic Merge tool

La magia

Para poder mostrar estos conflictos y resolver de manera automática aquellos en los que sea posible, analizamos los ficheros que el usuario nos pasa por parámetros, o a través de la pantalla inicial, si iniciamos sin parámetros (origen, destino y base).

Una vez hemos leído los ficheros y comprobado que no haya errores de análisis, creamos, para cada uno, un árbol semántico, similar a la ventana de clases que se puede ver en Visual Studio.

Semantic tree

Ya con estos árboles, comparamos el origen y el destino con la base para obtener lo que denominamos un árbol de diferencias. Finalmente comparamos estos árboles de diferencias para obtener los posibles conflictos y las diferentes formas de solucionarlos.

Escenarios

Hemos empleado cientos de horas de análisis, y procesado millones de repositorios para obtener las operacions y los conflictos más comunes, entre los que destacan:

  • Movidos divergentes: Si estamos haciendo refactor de nuestro código y movemos a diferentes partes del mismo (desarrollador A los prefiere por orden alfabético y desarrollador B los prefiere por orden de scope) detectamos el cambio y damos al usuario la opción de elegir.
  • Movidos/borrados: En caso de que un elemento (método, clase…) se haya movido en origen y se haya borrado en destino, lo detectamos y damos al usuario la opción de conservar el movido o el borrado.
  • Movidos + cambiados: En el caso de que un desarrollador mueva un método a otra clase y otro realice cambios en el mismo, se detectará automáticamente, y no habrá conflicto :)

Hay mucho más, disponible en semanticmerge.com

Integración

De momento, tenemos tutoriales sobre cómo integrarlo en Git, PlasticSCM, TFS y Perforce, y pronto deberíamos tener para Mercurial y SVN. Si usas otro sistema de control de versiones, avísanos!

Personalización

Mediante los parámetros de entrada, podemos especificar una herramienta de diff y merge personalizada, a través de los parámetros -emt y -edt de entrada. Además se puede especificar el tipo de fichero que estamos procesando aunque no tenga la extensión adecuada mediante el parámetro -t. En estos momentos el único lenguaje de programación soportado es C#, así que en este caso el único valor válido será text/csharp.

One more thing: Diferencias semánticas

Otra de las cosas que incorporamos es una herramienta de diff, que dados dos ficheros nos permite obtener las diferencias entre ellos.

difftool-included

Cómo se hizo

Aunque la idea ha estado en fase de análisis y diseño varios años, el desarrollo principal del proyecto se ha llevado a cabo en los úitimos 6 meses, en el que una buena parte del equipo de Códice ha estado implicada. Hemos estado divididos en dos grupos, uno encargado de las operaciones de merge y del backend de la herramienta, y otro grupo, que hemos estado cubriendo el diseño y la usabilidad de la herramienta.

Además, llevamos varias semanas usando la herramienta como herramienta de merge por defecto de manera interna, y las primeras betas privadas que distribuimos han tenido una acogida muy buena por parte de los voluntarios.

Bajo el capó

El lenguaje usado para todo el desarrollo de la app es C#, de ahí nuestro interés con que sea el primer lenguaje de programación soportado (llevamos semanas probando la herramienta a nivel interno).

La interfaz está desarrollada en WPF con algunos toques de Windows Forms, y para la ventana sin marco usamos la integración con Windows a través de Windows.Shell.

Las herramientas utilizadas han sido PlasticSCM como control de versiones, Visual Studio 2010 – 2012 como entorno de desarrollo y Blend 4 como herramienta de diseño de interfaces,

Pasos adicionales

Estamos en fase beta, con lo cual hay muchas cosas que pulir, además seguimos trabajando en mejorar la herramienta, la usabilidad, el diseño, la velocidad, así como el soporte para lenguajes adicionales y escenarios más complejos. Para ello hemos habilitado un portal en uservoice para recibir feedback de nuestros usuarios.

DVCS: La herramienta definitiva para un hackathon

Un hackaton es un evento social donde programadores y diseñadores compiten en grupos durante 24 – 48h en el desarrollo de la mejor aplicación para la plataforma elegida por los organizadores. En este tipo de eventos el tiempo es un factor clave, y la posibilidad de que un error en los últimos 5 minutos destroce horas de desarrollo es muy alta, ya que se viven momentos de muchísima tensión.

En estos casos es útil contar con un sistema de control de versiones para poder tener un registro de la evolución del proyecto, y evitar perder el rumbo original.

En el último Hackatón al que asistí hace unos días pude experimentar la frustración de grupos que usaban Team Foundation Services Preview, un sistema de control de versiones centralizado y en la nube. Es una herramienta muy potente para gestión de código fuente aunque muestra algunas debilidades para este escenario en concreto:

  • Necesita una conexión a internet estable y constante, ya que de otra manera no se puede realizar un check-in ni un checkout, y cada operación añade una carga adicional a la red.
  • Es centralizado, con lo cual cada vez que se hace un check-in se integra todo el código, y si había cambios en el servidor es necesario obtener primero la última revisión y luego integrarlo en local (manejando posibles conflictos, por supuesto) antes de poder enviar los cambios de vuelta, perdiendo ese preciado tiempo del que no se dispone.

Todo esto hace que se emplee el repositorio como una herramienta de sincronización, no como un control real de las versiones del código.

Veamos el mismo escenario con un sistema de control de versiones distribuido (DVCS):

  • Cada miembro del equipo puede desarrollar su código de manera independiente en una rama, y hacer commits frecuentes asegurando un mejor historial.
  • El resto de los miembros del equipo pueden replicar los cambios usando la red local, sin que sea necesario usar el ancho de banda, ni servidores externos.
  • Se puede controlar que otros equipos en la misma red no accedan al código, aunque compartan conexión a internet, mediante listas de control de acceso (ACL).
  • Las operaciones de merge son menos constantes, al hacer integración de componentes terminados, evitando riesgos de introducir errores de regresión. Además con tecnologías como Xmerge se puede detectar código refactorizado e integrar de una manera más sencilla.
  • Se pueden integrar los cambios en una rama principal sin que ello afecte al desarrollo del proyecto (una persona puede dedicarse a esa tarea, aunque no es necesario que lo haga de manera exclusiva).

PlasticSCM permite todas las características comentadas anteriormente y más, aunque hay otras herramientas como Git o Mercurial disponibles en el mercado.

Cuando el desarrollo es ágil (nada más ágil que un evento de esta magnitud) tener las herramientas adecuadas puede ser la diferencia entre una aplicación buena y una espectacular.

Para la próxima hackatón, te propongo usar un DVCS, y si escoges PlasticSCM, puedes dejar críticas y sugerencias en los comentarios.

Más información: