El modo desconectado de Visual Studio

11:21 0 Comments

A continuación se muestra un resumen del funcionamiento del modo desconectado de Visual Studio 2003/2005.

Cuando no tenemos conexión con el servidor de control de versiones, Visual Studio detecta esta situación y ofrece trabajar en modo desconectado. Aparecerá una ventana como ésta si estamos trabajando con Visual Studio 2003:


O como ésta si estamos trabajando con Visual Studio2005:


Para desconectar manualmente una solución tenemos que pulsar sobre Archivo --> Control de código fuente --> Cambiar control de código fuente ... y pulsar sobre el botón "Desconectar"

Una vez que hemos desonectado la solución, podemos seguir trabajando normalmente aunque no tengamos conexión con el servidor. Cuando queremos modificar un fichero, Visual Studio "simula" el checkout (desprotección). La desprotección no se ha enviado al servidor, por tanto es muy importante reconectar en cuanto se disponga nuevamente de conexión, ya que las modificaciones que se realizan mientras se está desconectado son exclusivamente locales al disco donde se están realizando.

La información sobre si una solución o sus proyectos están conectado o no con el control de código fuente, Visual Studio las almacena en los ficheros con extensión .suo (Solution User Options). Es muy importante que los ficheros .suo nunca estén bajo el control de versiones, sino que sean privados a cada workspace, ya que esta información es diferente para cada usuario.

Cuando una solución está desconectada, Visual Studio deduce el estado de los ficheros únicamente por el atributo de sólo lectura en el disco local. Es un fichero de sólo lectura estará protegido y uno writable estará desprotegido.

La única operación de control de código fuente disponible en modo desconectado es el checkout (desproteger). Cuando se hace un checkout a un fichero, Visual Studio simplemente quita la protección contra escritura a ese fichero en disco.

A la hora de reconectar, Visual Studio busca ficheros sin protección contra escritura y lanza checkouts reales contra el servidor de control de código fuente.

Adicionalmente, para cada fichero se hace un Diff(), y para aquellos que hayan cambiado en disco fuera del control de código fuente Visual Studio da un aviso, indicando que el contenido en disco es diferente del contenido en el control de código fuente:



Algunos problemas conocidos

Varios clientes han reportado en ocasiones problemas al utilizar el modo desconectado, que se enumeran a continuación:

Error no especificado al tratar de desconectar una proyecto o solución

Las pantallas de error que puede obtener son las siguientes (VS2003 y VS2005 respectivamente):





En ambos casos se trata de bugs de Visual Studio. Puede aprender más sobre este tipo de errores en la siguiente dirección:

http://alinconstantin.homeip.net/WebDocs/Scc/_UnspecifiedError.htm

Es más común encontrar fallos cuando se trata de proyectos Web, para los cuáles se recomienda seguir las siguientes pautas:

http://www.codicesoftware.com/releases/webDevelopmentwhitepaper.pdf

En caso de proyectos no Web, una buena práctica a seguir es colocar de forma adecuada en disco la solución y los proyectos. En Visual Studio 2003 ocurre que cuando el fichero de solución está en un directorio más interno que alguno de los proyectos que contiene, Visual Studio no es capaz de manejarlo bien.


Una forma muy sencilla de reproducir el caso es montar una solución con dos proyectos como se describe en la siguiente imagen:


Cuando no se tiene conexión con el servidor, se da un error controlado y aparece el diálogo para desconectar. Una vez que se pulsa en desconectar y se pulsa ok, aparece el "Error desconocido" citado anteriormente.

La forma de evitar este caso es refactorizar el fichero de solución modificando su ruta, de tal forma que la solución siempre esté en un directorio más externo que todos los proyectos que contiene. Algo parecido a la siguiente figura:

En Visual Studio 2005 este problema está corregido.

0 comentarios:

Ramas e integraciones con Delphi parte II

14:56 0 Comments

En la primera parte hablamos de la parte más básica de utilizar the Plastic SCM con Delphi. Ahora nos vamos a centrar en cómo gestionar las ramas y las integraciones y en cómo Plastic maneja el código fuente de Delphi.

Creación de ramas

Mi patrón de ramas preferido utilizando Plastic SCM es el de rama por tarea así que es lo que voy a hacer ahora: crearé un par de ramas y trabajaré en paralelo modificando el mismo código de manera diferente como harían dos desarrolladores. No me importa dónde hago los cambios y dejo que Plastic reconcilie los cambios una vez que haya terminado, para eso están la gestión de ramas y las integraciones, ¿no?.

¿Qué hay que hacer para crear una nueva rama en Plastic? Muy fácil: no tiene nada que ver con los comandos antiguos de copiar o instrucciones raras (bueno, se puede escribir cm mkbr si te gusta trabajar en línea de comandos, por supuesto), simplemente tienes que ir al explorador de ramas, hacer botón derecho en la rama desde la que se quiera crear una nueva y seleccionar "crear rama hija". Entonces saldrá el diálogo de crear una rama intelignete:



¿Qué es una rama inteligente? Pues es simplemente una rama que es capaz de recordar su punto de partida. Para explicarlo de manera simple; se le dice a la rama dónde están las fuentes que se quieren modificar y más adelante se puede modificar esta localización. En mi ejemplo le dije a Plastic que creara una rama denominada task001 que partiese de la etiqueta que había creado anteriormente: initial_version.

Nota: no, no es necesario escribir guión bajo en vez de espacios en los nombres de las etiquetas, se podría escribir una versión inicial y sería un nombre de etiqueta válido, pero habiendo utilizado el viejo DOS durante años no te acostumbras a que pueda funcionar realmente... ;-)

Después de crear la nueva rama, puedes ver el explorador de ramas como en la figura inferior, y puedes utilizarlo además para cambiar a esa rama y empezar a trabajar con ella.



También se puede ver la información de las propiedades de la rama y comprobar un pequeño esquema que muestra cómo está configurada la rama.



Trabajando en la primera tarea

Centrémonos ahora en el primer trabajo que tenemos que realizar: modificar el formulario para que tenga una mejor presentación, una parte para editar más ancha y fondo en verde. También modificaremos el código asociado al botón OnClick para realizar una acción diferente como muestra la figura de abajo.



Ahora utilizaré otra herramiente muy útil desde el menú de control de código fuente: la herramienta de revisión de cambios. Utilizando esta opción obtengo los siguientes resultados que muestras cómo he modificado el código del Button1Click.



Así que ahora puedo proteger mis primeros cambios: he modificado los ficheros .dfm y .pas.



Me acabo de dar cuenta de que no me gusta el cambio que acabo de hacer en el código (creo que ni siquiera está funcionando), así que vuelvo a modificar el fichero .pas y escribo el siguiente código:



Lo bueno de utilizar una rama para cada tarea es que no te tienes que preocupar de cuántos commits (o protecciones) haces: simplemente proteges cuando quieras guardar una copia, el código no irá a la línea principal del proyecto así que no afecta a nadie incluso si los cambios intermedios no compilan, y se puede seguir usando el control de versiones como mecanismo de versionado.

Finalmente cambiaré el fondo del formulario para que parezca más feo con color verde.



¿Qué ha cambiado en el fichero .dfm? Lo bueno de .dfm (al menos desde la versión 2, si recuerdo bien, cuando se convertían de formato binario a texto) es que toda la interfaz gráfica está definida en formato de texto (si, ahora estamos todos acostumbrados, pero Delphi era capaz de hacerlo...¡hace diez años!), con lo que se pueden utilizar fácilmente las herramientas de diferencias y de integraciones.



¿Que apariencia tiene mi explorador de ramas después de trabajar en la misma rama?



Colocar un gráfico en el formulario

Bien, consideramos lo siguiente: antes de que termine con la primera tarea de programación un segundo desarrollador comienza también a trabajar en la aplicación. Él ha incluido un gráfico en el formulario.

Comenzará a trabajar desde la última versión estable de nuestra aplicación de testing, que era intial_version. Su explorador de ramas tendrá la siguiente apariencia:



Por favor, ten en cuenta que he activado los enlaces de parentesco para esta captura, por esto ahora se ven las líneas amarillas que señalan desde una rama hasta su punto de partida.

El desarrollador añade un gráfico en el formulario que tiene la siguiente apariencia:



Hay que tener en cuenta que no estoy viendo el fondo verde ni el resto de cambios que ha realizado el otro desarrollador en task001 porque estoy partiendo de la última línea base estable.

Bueno, puedo oir que alguna dice: “eh, pero entonces tendrás que reorganizar todo el dfm manualmente después de hacer los cambios en paralelo”. Creedme, esto no es así.

Aquí podéis ver el árbol de versiones en 3D que muestra el fichero dfm que contiene la definición de la GUI:



Si, se puede ver claramente que el desarrollador de task001 ha realizado dos cambios en el formulario, y el de task002 tan solo ha realizado uno... ¡en paralelo!

Y para que las cosas sean un poco más complicadas también voy a modificar el evento OnClick escribiendo el siguiente código:



Integración de cambios

Es el momento de integrar los cambios en la línea principal. En este momento tu desarrollo tiene la siguiente apariencia:



Ahora tan sólo hay que ir al explorador de ramas, seleccionar botón derecho en la rama principal y en "cambiar a rama".

Entonces elegimos task001, damos al botón derecho y seleccionamos "integrar desde esta rama", entonces Plastic mostrará el diálogo de merge:



Estos son los dos ficheros que han sido modificados en la rama task001. No habrá ningún tipo de conflicto ya que es la primera rama que estamos integrando y desde entonces se ha modificado Unit2.dfm, no Unit2.pas. En la columna de los contribuidores se puede ver que dos de ellos tienen Source como contribuidor, lo cuál significa que se han realizado cambios sólo en task001 y no en la rama principal.´

Damos a la opción de "merge all" y Plastic realiza la integración.

Después de que está terminada la integración los ficheros que se han visto afectados se quedan en estado desprotegido por lo que se pueden proteger, compilar el código y verificar que todo se ha realizado correctamente.



También se puede comprobar desde el árbol de versiones del fichero Unit2.pas:



Muestra una nueva flecha verde que significa que se ha realizado un merge.

Este es el modo en el que se almacena el seguimiento de las integraciones.

He construido la aplicación y esta es la apariencia una vez que se ha integrado task001 (bueno, hasta ahora sólo task001 está en la rama principal):



Y aquí se puede ver cómo queda el explorador de ramas después de la primera integración, y los ficheros están protegidos:



Integración de task002

Integrar task001 ha sido muy sencillo: los cambios realizados en la rama se copian en la rama principal, no se realiza una verdadera integración entre las distintas revisiones.

Pero ahora con la rama task002 las cosas son diferentes ya que se han modificado los mismos ficheros que en task001.

Si se abre el diálogo de merge dando al botón derecho en la rama task002 y seleccionando "merge desde esta rama" se verá lo siguiente:



¿Qué es diferente ahora?

Hay que tener en cuenta que la columna de los contribuidores ahora dice que los ficheros se han cambiado tanto en la rama principal (después de integrar task001) como en task002.

Realizamos la integración y comprobamos como el fichero dfm se integra de manera automática, lo cual es una buena noticia.

La integración del fichero .pas necesita algo de ayuda: si te acuerdas, modificamos exactamente el mismo método dos veces de dos maneras diferentes, así que Plastic no sabe exactamente cómo resolver el conflicto.

Aquí aparece la herramienta de merge de tres vías:



¿Qué hay aquí?

El panel origen muestra el fichero que se está integrando desde task002. El panel base muestra Unit2.pas como estaba antes de que se realizaran los cambios: como estaba en initial_version. Y finalmente el panel de la derecha, el fichero de destino, muestra the Unit2.pas como está ahora en tu espacio de trabajo después de haber integrado la rama task001.

El panel inferior es el que muestra los resultados y propone agrupas los tres bloques, que es algo que se tendrá que modificar.

Por favor, ten en cuenta que la herramienta de merge de tres vías está detectando 3 conflictos, pero ha resuelto dos de ellos de manera automática ya que no estaban afectando a las mismas líneas de código.
Yo decido quedarme con los cambios de las dos tareas pero no con el de la base:



Todo integrado

¿Qué apariencia tiene mi formulario después de la integración? Bien, pues como esperabamos tiene el fondo del color de la tarea task001, el botón y la opción de editar modificados y el gráfico incluido en la tarea task002 como se puede ver debajo:



Lo mejor aquí es que ambos desarrolladores han podido centrarse en los cambios que tenían que realizar sin preocuparse el uno del otro hasta que terminaron sus modificaciones, y entonces Plastic se ha ocupado de integrarlas.

El árbol de versiones del fichero Unit2.pas ahora será:



Conclusión

En mi humilde opinión Delphi es aún uno de los entornos de desarrollo más potentes que existe, y por supuesto que se beneficia de todas las ventajas de una buena gestión de ramas y de integraciones. Plastic se puede integrar con Delphi con ayuda de SourceConneXion y parece que forman un equipo estupendo trabajando juntos.

Claro que como desarrollador que ha utilizado duranto mucho tiempo Delphi (he trabajado bastante tiempo con Kylix), es siempre un placer el poder ver cómo el equipo de Delphi gestiona la evolución de su herramienta.

0 comentarios:

Ramas e Integraciones con Delphi parte I

16:49 0 Comments

He pasado varios años programando en Delphi, desde la primera versión 1.0, hace más de diez años, a las estupendas versiones 6 y 7. Además he desarrollado con herramientas como TurboPascal, asi que cuando hace un par de días tuve la oportunidad de probar la última interfaz gráfica de Delphi y probar cómo funciona con Plastic, fué una experiencia de lo más gratificante.

Instalar la integración con Plastic

Al instalar Plastic para integrarse con Delphi, recuerda comprobar la opción de la integración con Visual Studio en el instalador. Plastic actualmente se integra con Delphi utilizando el SCC API, por lo que si no está instalado el plugin SCC no funcionará con Delphi.

Una vez que se ha instalado Plastic tendrás que descargar e instalar SourceConneXion. Está disponible en http://www.epocalipse.com/downloads.htm. Yo he probado la versión 3 y funciona perfectamente. Recuerda que tienes que descargar SourceConneXion y no VssConnection (como me pasó a mí la primera vez) ya que este último sólo funciona con Visual Source Safe.

Abre Delphi, y ve a la configuración Source Control\Tools\Provider, selecciona Plastic como control de versiones.



Ahora Plastic está instalado y funcionando.
Puedes mirar las opciones de configuración de Delphi para plugins (Source Control\Tools\Options) para poder configurar desprotecciones automáticas, etc.

Añadir un proyecto al control de versiones

Comencé con un proyecto muy sencillo Win32 que tan sólo contenía un formulario y un botón como se puede observar en la siguiente figura:



Entonces seleccioné botón derecho en mi proyecto y elegí la opción de añadir al control de versiones.



Si aún no tienes un espacio de trabajo en la localización de tu proyecto, Plastic te ayudará a crear uno. Tienes que poner tus proyectos de Delphi dentro de un espacio de trabajo de Plastic. Para proyectos Delphi normales (y complejos) se utilizará un espacio de trabajo de Plastic. Un espacio de trabajo es un lugar en disco en el que trabajar con los proyectos y Plastic sabe que tiene que controlar ahí todos los cambios.
Delphi crea una lista de los ficheros que se van a añadir y los muestra en un diálogo así que se puede decidir cuáles entran o los que se rechazan. En mi caso incluí un pequeño comentario explicando que se trataba de la importación inicial de código.



Empezar a trabajar

Una vez que el proyecto está bajo el control de código fuente se puede comenzar a trabajar. Otro desarrollador puede crear un nuevo espacio de trabajo en su máquina y descargar el código que acabas de añadir.

Yo probé un poco las funcionalidades de Delphi y creé un proyecto de pruebas DUnit, y lo puse bajo en control de código fuente. Entonces decidí cambiar los métodos de ejemplo de testing por lo que incluí una letra en el fichero. Protegí el fichero por lo que Delphi pregunta si quieres desproteger el fichero antes de hacer más modificaciones.



A partir de ahora el proceso será muy simple: las desprotecciones tendrán lugar de manera automática cada vez que el usuario comience a escribir en un fichero protegido. Para proteger los cambios simplemente hay que ir al menú del control de código fuente o seleccionar botón derecho en el fichero en el panel del Gestor del Proyecto.

Explorador del proyecto

En el menú del control de código fuente hay una opción muy interesante: el explorador del proyecto. Desde el mismo se puede observar el árbol completo del proyecto (muy sencillo en mi caso) y comprobar si los ficheros están o no desprotegidos.



El explorador del proyecto también es muy útil para seleccionar diversos ficheros y hacer desde ellos protecciones agrupadas.

Cambiar el tipo de un fichero

Plastic reconoce las extensiones de ficheros de Pascal pero puede ocurrir que estés utilizando una versión diferente de Delphi o que tengas bajo el control de versiones un fichero que Plastic haya definido con un tipo erróneo. Quiero decir, a lo mejor tienes un fichero binario que debería de haber sido identificado como texto o viceversa. Es importante para realizar búsqueda de diferencias y hacer integraciones ya que las herramientas que se utilizan para cada tipo de fichero son diferentes.

Si necesitas modificar el tipo de un fichero, simplemente ve a la herramienta gráfica de Plastic (también se puede hacer desde la línea de comandos pero la GUI es más sencilla), selecciona el fichero que quieras cambiar, da botón derecho y ve a la opción del menú de tipo.



También se puede hacer desde la historia del fichero.

Etiquetar el código fuente

Hasta ahora sólo he realizado algunas modificaciones en la rama principal por lo que mi explorador de ramas tiene la siguiente apariencia (ten en cuenta que para mostrar el explorador de ramas hay que ir a la interfaz gráfica de Plastic). Tan sólo hay algunos changesets disponibles pero no hay ninguna rama.



Lo primero que haré será crear una línea base con el código que tengo hasta ahora, por lo que tengo un buen punto de partida para utilizar durante el desarrollo. Quiero decir, tengo una versión de todo mi proyecto que sé que funciona, compila, pasa las pruebas, etc (si, aquí tengo un proyecto muy simple, pero estoy describiendo cómo deberían de ser las cosas).

Para hacer esto voy a la vista de etiquetas y seleccion crear una nueva etiqueta, pongo el nombre y los comentarios de la etiqueta que creo.



Por favor, recuerda que el etiquetado en Plastic es un proceso de dos pasos: primero se crea una nueva etiqueta y luego se aplica al espacio de trabajo. Así que aquí está el segundo paso.



¿Qué apariencia tiene mi explorador de ramas después de etiquetar? Mira la siguiente figurta.



En resumen

Hasta ahora hemos visto los pasos más básicos para comenzar un proyecto con So Delphi y Plastic SCM. Ahora sabemos cómo añadir un proyecto bajo el control de código fuente, realizar operaciones básicas, etiquetar una nueva versión...

En el siguiente post hablaré de ramas e integraciones utilizando un un proyecto de Delphi...

0 comentarios:

Futuro de los selectores y líneas de producto

12:46 0 Comments

Como posiblemente ya sepas, los selectores son el pilar central del sistema de plastic. Al empezar a trabajar en una rama, selecciona botón derecho en el menú de cambiar a rama, al hacer esto, por detrás se está configurando un selector.

El selector parece muy complicado al principio, y por eso hemos intentado esconderlo un poco tanto con las ramas inteligentes, cambiar a rama y cambiar a etiqueta.

Los usuarios avanzados se familiarizan rápidamente con el selector y es cuando le pueden sacar el máximo partido al sistema de múltiples repositorios, de múltiples servidores, etc.

Pero mi principal preocupación ahora es si hay algún modo de hacer que los selectores sean fáciles de utilizar para los nuevos usuarios.

He estado leyendo sobre Ruby las últimas dos semanas y me gusta lo simple pero potente que es.

¿Qué pasa si escribimos los selectores en Ruby? :-) Me temo que aún no es posible, pero me gustaría hacer que los selectores fueran más fáciles de entender.

Así que mi primer intento fué mejorar el editor de los selectores. He estado hablando con varios usuarios de plastic sobre diversas posibilidades. Una de ellas es crear algún tipo de asistente que ayudaría a los usuarios a designar los selectores. Es posiblemente la mejor opción pero quise explorar alternativas diferentes.

la alternativa más sencilla era la de mantener el código centrado pero consiguiendo mejorar el editor. Y aquí tenéis un par de capturas.



Bueno, lo único nuevo que se puede ver aquí es que el editor resalta la sintáxis. No es un gran paso, eso está claro, pero ayuda.

Lo bueno es que además da la posibilidad de completar el código para los repositorios, ramas y etiquetas.



¿Mejor? Supongo que facilitará las cosas.

Pero el lenguaje mágico que definimos para los selectores es aún muy complicado.

Mirad el selector por defecto:


repository "codice"
path "/project/doc"
branch "/main/doc"
checkout "/main/doc"
path "/"
branch "/main/task001"
checkout "/main/task001"


¿Qué significa?

Vamos a escribirlo de nuevo con una sintaxis diferente (just adding some syntactic sugar)


use repository "codice"
if path starts with "/project/doc"
download code from branch "/main/doc"
check out at branch "/main/doc"

if path starts with "/"
download code from branch "/main/task001"
check out at branch "/main/task001"


¿Mejor?

¿Te parece demasiado detallado? Si es así, podrías saltarte parte de la sintaxis o incluso pasar a sintaxis encriptada.

Lo bueno de la opción basada en if es que es más cercana al código, lo cual al final significa que se parece más a lo que estamos acostumbrados, ¿no?. Además, muestra claramente (espero) que hay un orden importante en las reglas del selector. El sistema intentará cargar la primera regla, después la segunda, y así consecutivamente. Esto no está tan claro con el selector actual.

En vez de sintaxis de descarga se da una opción más clara de leer/escribir que nos ha proporcionado Keith (¡un usuario de toda la potencia de plastic!):


use repository "codice"
if path startswith "/project/doc"
read from branch "/main/doc" //"from" is optional
write to branch "/main/doc" //"to" is optional
else if path startswith "/"
readwrite branch "/main/task001"


Puede incluso ser más corto (de nuevo sería más dificil para los nuevos usuarios pero los avanzados no tendrían ningún problema) reemplazando leer(read) por r o rw para leer y escribir (readwrite).

Creo que esta nueva sintaxis facilita mucho las cosas.

Pero aún creo que no es suficiente.

Una sintaxis realmente buena ofrecería incluso más posibilidades. Veamos lo siguiente:


use repository "codice"
if path starts with "/code"
find revisions where
attribute='status' and
attrvalue='validated' and
branch = 'br:/main/task001'
default
readwrite branch "/main"


¡Se podría incluso ir más allá!

Podrías definir en el selector consultas muy complejas. Recuerda que, al final, el selector es tan sólo un árbol que quiere decir "esto es lo que puedes descargar en tu espacio de trabajo". Si encontramos la sintaxis adecuada, incluso basa en código, los desarrolladores podrían escribir selectores avanzados para mapear sus repositorios en sus espacios de trabajo, realmente dando forma al contenido como quieran.

¿Hay algún motivo? ¿Por qué necesitarías darle forma a tus repositorios de manera diferente? ¿Para qué habría que crear estas variaciones?

Hey! ¿Dije variaciones? Si, eso dije. Entonces podríamos estar entrando en el mundo de líneas de producto. Leí sobre este tema por primera vez hace mucho tiempo (check Greenfield & Short book on software factories) y desde entonces siempre me ha preocupado cómo ayudar a gestionar familias de productos utilizando gestión de la configuración. Desde luego que las configuraciones de múltiples repositorios ayudan (puedes pasar a desarrollo orientado a componentes) pero no es suficiente.

Hay varios artículos sobre este tema, pero me pregunto si los selectores son el modo de trabajar aquí.

Supongamos que tienes algún tipo de catálogo central en el que almacenar las variaciones aprobadas de diversos componentes. Entonces podrías utilizar el selector para configurar un proyecto nuevo, seleccionando los componentes necesarios junto con sus versiones. Los componentes no tienen por qué limitarse a ficheros y directorios bajo el mismo árbol de directorios sino que podrían estar en diversos árboles y agruparse utilizando, por ejemplo, atributos, etiquetas o cualquier otro mecanismo.

Si, aún queda mucho por hacer, pero... ¡estamos haciendo los deberes!

0 comentarios:

El nuevo explorador de ramas y Mono 1.9.1

12:32 0 Comments

Acabamos de probar la última versión de mono con el nuevo explorador de ramas (BL102, incluyendo soporte de ramas "smart" y modificación del diseño de algunos elementos) en Linux.



¡Es genial!, ¿no?

0 comentarios:

Nueva versión con ramas "smart" disponible

12:51 0 Comments

Las ramas inteligentes cambia el modo de ramificar en plastic. Hace que sea más sencillo seleccionar los puntos de partida cuando se empieza a trabajar, muestran el estado de una rama y gestionan configuraciones con ramas de múltiples niveles.
Hace unas pocas semanas sacamos nuestra primera versión y ahora ya tenemos la segunda.
¿Qué es lo nuevo en la BL102?
Basicamente el diagrama de ramas se ha mejorado (de nuevo) y soporta una ampliación total, dibuja etiquetas de manera diferente (después de haber recibido opiniones de diversos clientes) y además presenta los enlaces a padres que son realmente los enlaces que muestran qué línea base, rama o changeset actúa como padre de una rama.
Mira las dos nuevas capturas:

Lá última muestra cómo funciona el zoom después de los últimos cambios.

Si quieres probar la versión BL102 puedes descargártela desde nuestra web aquí.

0 comentarios: