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.

Autor: Roberto Luis Bisbé

Software Developer, Computer Engineer

2 opiniones en “Merges un poco más inteligentes para C#”

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.