Mostrando entradas con la etiqueta Artículo Plastic. Mostrar todas las entradas
Mostrando entradas con la etiqueta Artículo Plastic. Mostrar todas las entradas

martes, marzo 25, 2014

Control de Código Fuente: Terminología común que hay que conocer

Por: Fernando D. Bozzo

Esta entrada fue motivada por las inquietudes de algunos de ustedes durante las pruebas que hicimos en marzo 2014, y que me recordaron que en este tema hay términos de uso común que el que recién comienza no domina (obviamente), y por eso quiero hacer una breve reseña de los términos más usados y de lo que significan, y que iré completando a medida que me hagan nuevas preguntas sobre "¿qué significa tal término?".

Para facilitar las cosas, pondré alguna imagen cuando sea necesario y relacionaré los términos con los de FoxPro cuando pueda aplicarse.



Workspace


El workspace, que se traduce como "espacio de trabajo", es un alias que se le asigna a un directorio. Así como en FoxPro podemos usar un alias para usar una tabla bajo otro nombre, donde el alias "clientes" apunta a "c:\un-directorio\clientes.dbf", el workspace es eso mismo, pero aplicado a un directorio, de modo que si creamos un workspace llamado "dvcs_vfp9" para referirnos al directorio "c:\desa\tests\dvcs_vfp9", realmente estamos creando ese alias para que sea más fácil de manejar en Plastic, ya que es más cómodo mostrar un alias significativo en una de las solapas superiores que todo el nombre de un directorio, lo que dejaría poco lugar para las solapas de otros workspaces. De modo que hablar de "workspace" y de "directorio de trabajo" es lo mismo.

Vista del workspace "vfp_test_grupo" y el directorio que representa en Plastic





Checkin y Checkout



Check-in significa algo así como "verificar o realizar entrada", que es lo opuesto a Check-out, que es "verificar o realizar salida". Tanto la entrada como la salida se refiere a archivos, entrada o salida de archivos, o lo que es lo mismo, enviar/subir (checkin) o recuperar/bajar (checkout) archivos al servidor del Control de Código fuente.

El paralelismo con FoxPro sería el buffering de tablas, donde uno agrega, elimina o modifica registros en vez de archivos, en cualquier momento se pueden comprobar qué registros han cambiado con GetFldState (en Plastic se revisa la vista de Cambios Pendientes que actúa sobre los archivos del workspace) y luego se confirma la grabación de los mismos con TableUpdate (equivale al Check-in) o bien se pueden deshacer todos los cambios usando TableRevert (en Plastic equivale a "Deshacer Cambios"). El Checkout en Plastic solo es un estado que indica si un archivo está marcado para modificar o no. En otros SCM el checkout es la operación que se baja la última versión de un archivo al workspace, pero en Plastic esto se hace seleccionando un workspace por su solapa, o eligiendo "Actualizar workspace" en la vista de Items, o con el comando cm getfile en una ventana de comandos DOS.



Hacer un "Diff"


Versión corta: Hacer un Diff es buscar y mostrar las "Diferencias" (Differences en Inglés) entre dos archivos. Se usa para saber qué líneas o bloques de código se han cambiado entre dos versiones de un programa, por ejemplo trabajamos un rato en un programa, donde vamos guardando los cambios cada tanto (con checkin) y luego queremos ver los últimos cambios visualmente (a diferencia de tener que recordarlos)
Para la versión larga aplicada a Plastic, leer este artículo.



Hacer un "Merge"


Versión corta: Hacer un Merge es realizar la mezcla de las modificaciones hechas por separado a un mismo programa, para volver a tener un solo programa que tenga todos los cambios. Si yo tengo un programa copiado en dos directorios, a una copia le agrego un método "A" y a la otra copia le agrego un método "B", el merge sería tomar el programa original y agregarle los métodos "A" y "B".
Para la versión larga aplicada a Plastic, leer este artículo.



Cherry Pick


Versión corta: Es un tipo de Merge que permite seleccionar changesets o ramas específicas, sin incluir el resto de archivos heredados.
Para la versión larga aplicada a Plastic, leer este artículo.



Rama


Una rama es una línea paralela de trabajo, una copia completa del workspace (o directorio del proyecto) en la cuál poder trabajar sabiendo que a la copia original no la afectamos en lo más mínimo.
Una rama está compuesta por uno o más changesets.
En la práctica es como hacerse una copia del sistema en otro directorio y trabajar en él para, al terminar, pasar los cambios al directorio original.

Para la versión larga aplicada a Plastic, leer este artículo.

Imagen de la rama v1.19.17 de FoxBin2Prg con 4 changesets y una etiqueta de versión




Repositorio


En Plastic un repositorio es una base de datos (archivos de SQL Server, MySQL, etc) que contienen un grupo de tablas y esquemas que contendrán los archivos y relaciones que se hagan entre ellos.

Los archivos contenidos serán los que nosotros "subamos" al control de código, mediante las opciones "Agregar al control de código" o mediante los "checkin", y que también se pueden marcar opcionalmente como modificables con un checkout.

Normalmente se usa un repositorio por cada proyecto.



Changeset


"Changeset" significa "juego de cambios" o "conjunto de cambios", y se usa para identificar las operaciones de agregado, borrado o modificación hechos a uno o varios archivos que luego se guardan con checkin.
En Plastic se puede ver el contenido de las operaciones de un changeset haciendo doble click sobre uno de ellos.

Ejemplo de las operaciones contenidas en un changeset (archivos Movidos, Borrados y Añadidos):




Lista de archivos ignorados (ignore.conf)


Los archivos ignorados son aquellos archivos Privados que no nos interesa ver en la vista de Items de Plastic para mantenerla más despejada y poder enfocarnos en los archivos que sí nos interesa controlar. Es un filtro, un archivo de texto que contiene una lista de archivos o especificaciones de archivo donde generalmente se suelen anotar los .tmp (temporales), .fxp (compilados), .bak (backups), y demás archivos que no queramos ver.

Ejemplo de parte de un ignore.conf:

*.FXP
*.LNK
!/_iniciar aqui.lnk
*.SCC
*.TMP
*.BAK
*.ZIP
*.7Z

foxuser.dbf
*/FXUResults.*




Detalle de la especificación: 


En el ejemplo anterior tenemos los 4 tipos de ignore soportados, que se interpretan como un filtro con la función LIKE() en FoxPro:
  • La extensión sola (ej: *.FXP): Se ignoran todos los .fxp dentro del workspace, incluyendo subdirectorios
  • Un nombre de archivo (ej: foxuser.dbf): Se ignora el archivo indicado dentro del workspace, incluyendo subdirectorios
  • Un directorio con especificación de archivo (ej: */FXUResults.*): Se ignora el archivo dentro del directorio indicado. La raíz del workspace siempre es "/", que como se ve no es la contrabarra de Windows, sino el signo dividido que se usa en Linux y Mac para los directorios, ya que Plastic es multiplataforma
  • Una excepción a la regla (ej: !/_iniciar aqui.lnk): Este tipo realmente actúa como "anti-filtro" y es muy útil en los casos en los que tenemos definido un filtro, pero no queremos que se aplique en un directorio en particular. En el ejemplo dado se ignoran todos los accesos directos (*.lnk), pero se exceptúa de esta regla a un archivo en particular que está en la raíz y que se usa para abrir una sesión de FoxPro


Lista de archivos cloaked (cloaked.conf):


Los archivos cloaked son aquellos archivos controlados por Plastic, donde no nos interesa que se vuelvan a descargar o actualizar desde la base de datos.
Su uso habitual es para evitar que algunos archivos pesados (como un DBF con datos o un binario) se descarguen cada vez que actualizamos el workspace o nos cambiamos de changeset.
Se usa mucho en la industria del videojuego, donde ciertos mapas de textura pueden tener cientos de MB que tardarían un buen rato en descargarse y que al programador no le aporta nada para sus pruebas.

En FoxPro, un buen caso de uso podría ser el archivo "/_iniciar aqui.lnk" del ejemplo anterior, donde por un lado nos interesa controlarlo con Plastic para que todos los programadores se lo puedan descargar y que luego cada uno lo pueda personalizar según dónde tenga instalado FoxPro, poniéndolo en el cloaked.conf para que no se le vuelva a descargar y se pierda su configuración particular.

La especificación de archivos es la misma que para los ignorados.



Lista de cambios ocultos (hidden_changes.conf):


Los "cambios ocultos", como podría llegar a deducirse, son los archivos controlados por Plastic que no queremos ver en la vista de Cambios Pendientes aunque hayan sido modificados.
Un ejemplo podría un archivo LOG que se protegió inicialmente vacío, pero que suele cambiar frecuentemente y cuyo contenido no nos interesa que se guarde en la base de datos.

La especificación de archivos es la misma que para los ignorados.




Nivelar una rama


Nivelar una rama significa actualizarla con el contenido más actualizado de otra rama, y se hace tomando el contenido de otra rama (origen) y haciendo un merge sobre la rama a nivelar (destino).

Para nivelar una rama se debe estar ubicado sobre ella, en el último changeset más actualizado (en Plastic es donde se debe ubicar la casa)

Para la versión larga aplicada a Plastic, leer este artículo.



Si creen que faltan términos, me comentan y los voy agregando.


Saludos!



martes, marzo 18, 2014

PlasticSCM: ¿Qué es el Merge?

27/09/2014 - Actualizadas algunas partes de "Qué son los conflictos de un merge"
16/09/2014 - Actualizado con explicación de "Qué son los conflictos de un merge"
02/04/2014 - Actualizado con explicación de la opción "Proteger los cambios a otra rama..."

Por: Fernando D. Bozzo

El Merge es la operación que permite "mezclar" el código correspondiente a dos modificaciones simultáneas hechas en paralelo a un mismo programa.

Para quienes vienen de usar SourceSafe con FoxPro, esto es algo casi desconocido, porque con SourceSafe se usaba el scctext.prg que venía de serie y que sólo permitía hacer Diff. Algunos más aventurados puede que hayan intentado usar TwoFox para generar vistas XML de las clases e intentar hacer un merge manual, pero quienes lo hayan usado sabrán el cuidado que había que tener con no tocar ningún tag XML que nada tenía que ver con la programación y que dificultaba bastante entender lo que se estaba tocando.

La vida con SourceSafe era: o toco yo, o toca él, pero los dos no! La única excepción eran los PRG, que al ser texto sí que permitían más libertad, pero para todo lo demás, los checkout eran exclusivos, lo que significa que si un desarrollador bloqueaba una librería, nadie más podía modificarla hasta que ese desarrollador finalizara sus cambios, ¡y qué problemas se generaban si se enfermaba o se iba de vacaciones y la dejaba así! Claro que siempre se podía recurrir al truco de quitar el atributo de read only del archivo y modificarlo, pero subir los cambios al proyecto era imposible, y esto a muchos proyectos los bloqueaba literalmente, o como mínimo los retrasaba.


Volviendo al presente, las cosas cambiaron en FoxPro, y ahora con FoxBin2Prg un mismo programa, como clases, forms, menús, etc, puede ser modificado por varios desarrolladores de forma simultánea, cada uno en su equipo, y al momento de subir esas modificaciones al control de código se puede hacer el merge, en algunos casos de forma automática (para el primero en llegar: ¡siempre es automático!:) y en otros casos de forma manual.


[27/09/2014 - 16/09/2014 - Actualizado >>]

¿Qué son los conflictos de un Merge?


Cuando se hacen modificaciones sobre un mismo componente pero en distintas ramas, al tener que mezclar los cambios es probable que haya que resolver (seleccionar/mezclar) las diferencias entre 2 modificaciones realizadas al mismo form, clase, etc, de forma que tanto los cambios de una rama como de la otra queden incluidos.

Las ramas a mezclar pueden ser, por ejemplo, distintas características hechas por uno o más desarrolladores trabajando en paralelo, como una rama para cambiar el aspecto visual y otra rama para cambiar la funcionalidad de un botón de comando, lo que permite que al final se pueda seleccionar la característica o funcionalidad que se quiere incorporar individualmente y mezclarlas para obtener el resultado completo final.

Al trabajar en funcionalidades en ramas paralelas, es probable que se modifique algo en común, como una propiedad o un método, lo que provocará un conflicto al hacer el merge, que podrá ser automático o manual dependiendo de la calidad del algoritmo de la herramienta y de las características del código (si está bien estructurado, encapsulado y normalizado, será más fácil)

La idea de generar código estilo PRG con FoxBin2Prg, es justamente para que a la hora de hacer un merge sea casi tán fácil como hacerlo con un PRG de verdad, y dado que conocemos el lenguaje, ver el código de esta forma nos facilita la tarea lo más posible, ya que no hay que lidiar con códigos o símbolos extraños, sino sólo con el PRG y con los metadatos que se muestran como comentarios, donde suele ser muy poco lo que debe hacerse.

Obviamente, es necesario entender qué hace el código antes de realizar esta operación, y en eso ayuda bastante usar la nomenclatura de objetos y variables que dan una idea conceptual de para qué sirve cada cosa y qué tipo de dato maneja.
[<<]

Para los que les toque hacerlo de forma manual, los SCM traen herramientas para realizar la tarea, que suele mostrar las dos versiones del programa a unificar en dos paneles izquierdo-derecho. En la siguiente imagen se puede ver un ejemplo de WinMerge, un programa para Windows gratuito que permite ver diferencias entre archivos:



Este tipo de vista es muy útil cuando comparamos dos momentos de la historia del mismo archivo, como la versión de ayer y las modificaciones de hoy, pero no sirve cuando se quieren comparar 3 archivos, donde uno es la base, o sea, de donde partieron los otros dos archivos, el segundo es el mismo archivo base, pero modificado por un desarrollador y el tercero es el mismo archivo base, pero modificado por otro desarrollador.

En esta situación se requiere un visualizador de 3 vías, que muestre la base y los 2 cambios, y el programa que incorpora Plastic para esta tarea es increíble:


En la imagen puede verse en el panel izquierdo (Source, u Origen) los cambios que hizo Dev-2, que agregó Los métodos pagCalculos.Activate y cmdCalcular.Click (abajo se ve el nombre entero), pero resulta que mientras él estaba programando este cambio, Dev-1 terminó el suyo antes y lo mergeó primero (panel derecho, que es Destination o Destino) donde se ve que agregó en el mismo form el método pagDatos.Activate, seguramente con un merge automático en el que no tuvo que hacer nada.

En el panel central se ve el código original (Base) antes de que ambos hicieran sus cambios, que si bien en este caso no muestra cambios en sí mismo, cuando los muestra lo hace coloreado en amarillo.


En la cabecera de los tres paneles, los títulos coloreados Source, Base y Destination, además son selectores de cambios:



donde al clickearlos sus cambios se activan o desactivan en el panel inferior que muestra el resultado. En este caso están habilitados los cambios de ambos desarrolladores en el panel izquierdo de Dev-2 y en el derecho de Dev-1, por lo que aquí se muestra cómo quedaría la mezcla de los mismos:


Algo que también se puede ver, aunque no resulte evidente, es que esta mezcla se muestra bien y con lógica coherente porque la nomenclatura usada le permite a los algoritmos internos de la herramienta diferenciar ambos cambios y gracias a eso no es necesario modificar nada a mano.

Esto último lo comento porque puede darse el caso de que, incluso con una buena nomenclatura, dada la complejidad de los cambios puedan presentarse varias diferencias que puedan no ser coherentes para quien las esté mirando, y que requieran modificar o mover manualmente líneas o bloques de código para terminar de ajustar el merge, que también consiste en eso. Este panel inferior permite hacer dichas modificaciones manuales.

Por ejemplo, uno de los casos que puede requerir modificación manual, es cuando se trabaja con un pageframe y mientras otro desarrollador agrega una página y hace checkin, nosotros modificamos algo en la actual y hacemos checkin. Como nosotros teníamos una página de menos, podría ser necesario actualizar el PageCount manualmente.
Quice hacer esta prueba para hacerles una captura, pero resulta que Plastic me hizo este cambio de forma automática y me dejó sin nada que hacer ;-)

Igualmente hago la captura para que lo vean: La zona horizontal del medio es donde está el PageCount, el panel izquierdo tiene mis cambios, que en esta parte del código no tengo, en el medio está el origen del que partí y donde se vé que había 2 páginas, y el de la derecha es el destino, o sea, donde estoy intentando hacer el merge, y automáticamente desactivó los cambios 1 (Origen) y 2 (Base) y seleccionó el del panel 3 (Destino), además se puede observar en la parte superior izquierda el título:

"Tipo de conflicto: Automático. No es necesaria la intervención del usuario"... =D


También puede verse en la cabecera, que de los 10 cambios detectados, solo 1 no es automático!, o sea que los otros 9 los resolvió automáticamente por los algoritmos internos, y yo debo resolver el restante, que en este caso es este:


Observen que el selector de cambios (izquierda) y el selector de cambios no automáticos (derecha) tienen botones de navegación independientes, lo que permite navegar por todos los cambios o solo por los cambios no automáticos (1 en este caso). Revisar todos los cambios es buena idea, aunque sea para asegurarse de que la parte automática fue bien resuelta.

Solo para que vean como resolví este cambio manual, desactivé los cambios del lado izquierdo, ya que pueden verse que un poco más arriba (imagen de abajo), aunque en este caso daba igual, porque con el lado izquierdo activo ya los marcaba tachados antes, lo que significa que no se iban a incluir esas líneas, pero que igualmente requería nuestro visto bueno.

El caso anterior se podía resolver de dos formas:
  1. Desmarcando el Origen y dejando solamente la Base y el Destino (fue como lo hice)
  2. Eligiendo el botón superior que en la captura anterior decía "Marcar como resuelto", ya que las líneas tachadas iban a excluirse de todas formas
Nota: Es importante comprobar siempre todos los cambios, y si la activación o desactivación de los paneles superiores no ofrece el resultado esperado, siempre se puede recurrir al 4 panel (el inferior, de resultado) donde se puede modificar manualmente.


Así quedó la resolución del conflicto anterior, donde desmarqué el origen:


Finalmente, se guardan los cambios de este merge con el botón superior izquierdo, lo que cerrará esta ventana y puede que muestre otros merges para hacer.

Hay 3 cosas importantes que se deben conocer y recordar en esta etapa:

  1. Que si se necesita dejar esto para luego, se puede cerrar la ventana de merge "sin guardar cambios". Si hubiera muchos archivos por resolver, al cerrar la ventana se puede ver brevemente el botón "Cancelar" en la principal, al que hay que darle rápido antes de que aparezca una nueva ventana de merge. Parece un juego, pero es algo que deberían mejorar en la interfaz :D
  2. Que una vez guardados los cambios del merge, quedarán todavía los binarios de FoxPro, los cuales se deben seleccionar e ignorar, ya que luego deberán regenerarse en la siguiente ventana de Cambios Pendientes, ya que el merge en Plastic tiene 2 etapas: Procesar Merge, donde se resuelven los conflictos, y Regeneración de binarios y Checkin en la ventana de Cambios Pendientes.
  3. Que una vez se esté en la ventana de Cambios Pendientes, se debe recordar que por haber hecho un Merge con las versiones texto ¡los binarios que hay allí no sirven y hay que regenerarlos!

Comento un poco más estas opciones, ya que cuando hagan merge será vuestro día a día.

En el ejemplo anterior yo cancelé el merge porque solo quería mostrarles la pantalla, así que "cerré sin guardar cambios" (o sea, hice el paso 1)

El paso 2 implica seleccionar todos los binarios que se muestran en esta ventana de Merge y descartarlos, lo que significa dejar los que ya existen en el workspace (también llamado Destino), ya que han quedado desactualizados porque los cambios reales del Merge los hicimos en las versiones texto, como vemos en la siguiente imagen:


Nota: Si hubiera confirmado los cambios del merge, esta ventana no mostaría ahora las versiones de texto de los archivos, ya que hubieran pasado a la ventana de Cambios Pendientes.

El paso 3 ya se realiza en la ventana de Cambios Pendientes, pero a diferencia de lo que venimos haciendo cuando modificamos un binario en el IDE de FoxPro (generar texto y luego binario), en este caso solo debemos regenerar el binario, ya que es el texto el que estuvimos modificando. Si no lo hacemos así, perderemos todos los cambios del merge y nos estaremos quedando con los archivos binarios del workspace y en el peor caso también con las versiones texto mezcladas que ya no corresponderán a esos binarios!

Lo repito para remarcar: Luego de un Merge, mandan siempre las versiones texto, ya que es con lo que se ha trabajado en esta operación, por lo que sólo se deben regenerar los binarios usando el script de "Cambios Pendientes: Regenerar Binarios".

Y luego se hace el checkin para guardar todo.

Les dejo un video de ejemplo con explicación incluida:
http://youtu.be/ytMpWP69YMo


[02/04/2014 - Actualizado >>]
Respecto al checkin hay una opción que debemos conocer, y que es "Proteger los cambios a otra rama...", y la verdad es que es una opción muy útil que me ha tocado usar más de una vez.

Imaginemos que abrimos FoxPro en el workspace y comenzamos a trabajar, hacemos algunos cambios, algunas pruebas y vamos a Plastic para guardar los cambios, pero nos encontramos con que, sin quererlo, estábamos trabajando en la rama principal (esa en la que no se deben hacer cambios directamente, sino solo merge :-) y nos olvidamos de crear una rama nueva para trabajar. ¡Por Dios! ¿qué hacemos ahora? Fácil: usamos esta opción y creamos el changeset en una nueva rama, todo en un mismo paso:


Se nos pregunta el nombre de la rama y al confirmar nuestros cambios irán directamente a ella, dejando la rama principal como estaba.

En esta pantalla donde nombramos la nueva rama además tenemos otra opción interesante, que es un checkbox que nos permite pasar los cambios a la nueva rama, pero sin hacer checkin (por defecto hace checkin), lo que viene muy bien si solo queremos pasar nuestros cambios aún sin terminar a la nueva rama para hacer más tarde el checkin nosotros cuando realmente hayamos acabado los cambios:



[<<]


Como nota final, es interesante saber que este programa de merge se puede usar por separado, o sea, viene con Plastic y está un su directorio de instalación, pero se puede ejecutar por separado. Se llama "mergetool.exe" y tiene una opción dedicada en le menú de Windows, dentro del menú "Client Tools" de Plastic.

Nada más por hoy.

Hasta la próxima entrada! :D




lunes, marzo 17, 2014

PlasticSCM: ¿Qué es el Diff?

[03/04/2014 - Actualizado con la opción de Diff modificable si se hace checkout del archivo]

Por: Fernando D. Bozzo

El Diff es una operación para obtener las diferencias entre dos archivos, o entre dos versiones del mismo archivo, y se usa para poder ver de un vistazo qué ha cambiado.

En general todas las herramientas de control de código fuente incorporan alguna herramienta de Diff, e incluso existen herramientas externas que permiten comparar diferencias entre archivos o incluso entre directorios, como el WinMerge (gratuito) o el EditPlus (de pago).


En Plastic hay varias formas de invocar un Diff, se puede desde la vista de Cambios Pendientes, desde la de Items, desde la vista del Explorador de ramas, etc, y se pueden comparar dos momentos cualquiera de la historia de un archivo o de un changeset (conjunto de archivos y/o directorios), por lo que no solo se pueden ver los cambios hechos en un archivo, sino también los cambios hechos de un changeset a otro, donde por ejemplo, se puede ver si se agregó, modificó o eliminó un archivo o directorio.


En la siguiente imagen se puede ver una parte de la historia de FoxBin2Prg comprendida etre la versión v1.16 y la v1.17, donde se desarrolló el soporte para trabajar en modo Batch y además se solucionaron algunas incidencias reportadas del soporte de menús de la versión anterior.

Los dos changesets que tienen los círculos verdes (etiquetas de versión) corresponden a la rama principal, y los dos changesets de más abajo corresponden a la rama de desarrollo que comenzó en la v1.16


Si queremos ver las diferencias entre estos dos changesets, marcamos (click) el de la derecha, y luego marcamos (ctrl+click) el de la izquierda, veremos como se iluminan o aclaran al seleccionarlos.

Acto seguido hacemos click-derecho sobre cualquiera de los dos y elegimos "Mostrar diferencias entre changesets seleccionados", lo que enviará la información de estos dos changesets a la herramienta interna de Diff para que los compare. En la imagen de abajo se puede ver el Diff resultante (click en la imagen para ampliar):




En la parte superior de la imagen se puede ver la información del changeset: nombre de usuario (fernando), número de changeset (cs:128), fecha/hora y comentarios sobre el desarrollo y las modificaciones realizadas.



Bajo esa sección hay una barra con controles para navegar entre los archivos que se muestran en el panel de debajo, un botón de estadísticas y a la derecha de todo un filtro que permite ubicar rápidamente uno o varios archivos escribiendo parte del nombre.




Luego está el panel de archivos, donde se puede ver:   Cambiados: 5 elementos
con los 5 archivos modificados, y luego se ve:   Añadidos: 12 elementos
con los 12 archivos que fueron agregados, de los que solo se ve el primero



Bajo este panel hay una barra de controles para navegar por las diferencias, un contador de diferencias, un menú de Opciones donde se pueden configurar varios aspectos sobre cómo ver las diferencias, si se deben ignorar fines de línea y espacios en blanco, codificación de caracteres, etc, y una opción de búsqueda para ubicar algo rápidamente.



Finalmente está el panel de diferencias, donde en la parte superior de cada uno, a modo de cabecera, se muestra que changeset se está viendo, de qué rama y qué usuario lo creó. En este ejemplo se está comparando el changeset cs:125 contra el cs:128, y debajo está el código, donde el antiguo está del lado izquierdo y el más nuevo del derecho.



Entre ambos paneles de código hay una serie áreas grises que suelen mostrar los bloques de código coincidentes que se han modificado, agregado o quitado, y unas áreas violeta que muestran los bloques movidos de un sitio a otro (en este caso, en el menú de opciones superior tengo habilitada la detección de bloques movidos)

[03/04/2014 - Actualizado >>]
Hay una opción muy interesante en el Diff, que solo se habilita si de los archivos que comparamos, al del workspace le hacemos previamente checkout, y lo que se habilita permite seguir editando el archivo del workspace desde la ventana del merge, no solo como un editor de código manual, sino también permitiendo pasar bloques de modificaciones del panel izquierdo (versión histórica del archivo) al panel derecho (archivo del workspace) o incluso permitiendo desactivar grupos de cambios con una "x" que aparece en el bloque cuando corresponda. Los 3 tipos de edición se pueden apreciar en esta imagen:


Una vez realizados los cambios, se pueden confirmar con el botón "Save" o descartar con "Discard".
[<<]


Aprender a usar bien esta herramienta y conocer y probar sus opciones nos permitirá poder hacer las comparaciones de forma óptima, ahorrando un montón de tiempo.


Hasta la próxima!

domingo, marzo 16, 2014

PlasticSCM: Cómo trabajar en FoxPro 9 con ramas por tarea

Por: Fernando D. Bozzo

En esta ocasión vamos ver una forma de trabajar con ramas, que sirve tanto para uno como para varios desarrolladores. Si no sabes lo que es una rama, antes de seguir te convendría leer el artículo anterior sobre este tema: PlasticSCM: Cómo crear una rama para comenzar a trabajar


La norma básica a seguir es muy simple: Jamás hacer cambios en la rama principal!. Nunca!


(Bueno, las únicas excepciones son el primer add/checkin con un archivo README.txt, que recomiendo absolutamente, y la subida del proyecto FoxPro 9, que será el segundo add/checkin)

A partir de quí, lo único que se debe hacer en la rama Principal es el merge final de las demás ramas para etiquetar la versión. Todo el trabajo se debe hacer en ramas derivadas de la principal.

Antes de continuar un aviso: Para todo lo que sigue voy a asumir que la estructura de directorios de tu proyecto está encapsulada de forma que en la raíz está el proyecto (pjx) y el programa principal, y en los subdirectorios están los componentes, y que no se referencian componentes externos a esta estructura de directorios, por ejemplo apuntando a otra aplicación o ubicación de librerías como las FFC de FoxPro. Si esto no se cumple entonces no podrás obtener todas las ventajas de trabajar con control de código por las dependencias externas que tengas y tal vez de convendría leer antes: Crear un proyecto FoxPro: ¿por dónde comenzar?


Pasos a seguir para comenzar a trabajar con un proyecto nuevo


En este caso tenemos un proyecto FoxPro 9 que se crea desde cero y que desde el mismo inicio se pone bajo control de código.






Cómo agregar un proyecto existente al control de código para trabajar


Este es el caso típico para muchos desarrolladores que tienen proyectos hechos, y que ahora deciden meterlos en control de código para continuar trabajando de esta forma.
Los pasos para agregar un proyecto FoxPro existente al control de código está explicado en este artículo.
Para comenzar a trabajar con este proyecto FoxPro ya controlado, ver el siguiente punto.


Pasos a seguir para comenzar a trabajar con un proyecto existente


En este caso tenemos un proyecto FoxPro 9 que ya estaba bajo control de código fuente previamente, por lo que los nuevos desarrolladores solo deben unirse para tener lo último, crearse sus ramas y comenzar a trabajar en ellas, por lo que deben:
  • Crear el directorio en el disco donde se alojará el proyecto FoxPro 9 (ojo, el directorio vacío!)
  • Crear el repositorio Plastic para el proyecto
  • Crear el workspace asociado al directorio para poder actualizar el repositorio
  • Sincronizar el repositorio Plastic local con el repositorio remoto (esto se bajará el proyecto con archivos y directorios)
  • Crear una rama personal de desarrollo desde el último changeset de la rama Principal
  • Ya se puede comenzar a trabajar en la rama de desarrollo

Ejemplo de la rama de desarrollo v1.19.17 de FoxBin2Prg, que se creo a partir de la última versión v1.19.16 (círculo verde) de la rama Principal /main. Al finalizar se hará merge de la v1.19.17 de desarrollo en la rama principal nuevamente y se etiquetará la nueva versión como v1.19.17



Trabajo en ramas cuando se trabaja en solitario


Este caso es el que uso para trabajar en FoxBin2Prg, y es el modo de trabajo mínimo recomendado.

Se basa en tener:
  • La rama principal (/main) donde solo se hará merge y se etiquetarán las versiones
  • La rama secundaria para desarrollar
  • Alguna rama puntual para solucionar incidencias solamente

Pantallazo de un momento del historial de FoxBin2Prg
(click en la imagen para agrandarlo):


Como puede verse en la captura anterior, en la versión v1.15 de la rama principal hice una rama secundaria de desarrollo para trabajar en el soporte de los menús (MNX) que llamé "Soporte_MNX" (la tarea a realizar) y que luego se convertiría en la versión v1.16.

Mientras estaba trabajando en esta tarea descubrí un error en el soporte OLE de los forms y clases, lo que debía arreglar y promocionar cuanto antes, pero sin incluir nada del nuevo desarrollo. Y es en ese momento que abro una nueva rama desde la v1.15 para hacer el parche v1.15p1
Se puede ver gráficamente que con el arreglo hecho en ese parche (un solo changeset) luego hice un merge en la rama principal, que hizo la versión v1.15p1 pública y también hice un merge en la rama de desarrollo del Soporte_MNX, ya que de otra forma si no lo hiciera así, en la siguiente versión estaría incorporando nuevamente el error que había solucionado.

Al finalizar el trabajo en esta tarea, hice el merge final en la rama principal, que etiqueté como v1.16 pública e hice una nueva rama para comenzar a trabajar en el soporte para Proceso en modo Batch. En este punto Fidel Charny me reportó una incidencia sobre el posicionamiento del menú, pero esta vez en vez de crear una rama aparte para el parche, lo mezclé en la tarea actual, en el segundo changeset de "ProcesoEnModoBatch" y liberé todo junto al día siguiente como versión v1.17. Esto lo hice así porque tanto el desarrollo de la tarea como el parche los hice en un corto período de tiempo (1 día) y no valía la pena separarlos en versiones distintas.

Sobre la conveniencia de crear un parche y versionarla por separado solo con los arreglos o hacer los arreglos dentro de la rama de desarrollo para sacar todo junto en la siguiente versión, todo depende del tipo de desarrollo que se esté haciendo y de los tiempos que se manejen.

Para un programa como FoxBin2Prg, cualquiera de las dos formas de trabajo es válida porque es un conversor y no un aplicativo comercial, y en este caso el baremo que usé es de fechas: Si el desarrollo que estaba haciendo iba para largo y surgía algún reporte de bugs en medio, no podía dejar colgados a todos con el error hasta que termine el desarrolo actual, por lo que lo conveniente era sacar y versionar un parche por separado para luego poder seguir con el desarrollo actual. Pero si el desarrollo iba a ser rápido y surgía algún reporte de fallo, entonces sí hacía el arreglo en la rama de desarrollo actual y versionaba todo junto.

Como ahora el desarrollo de FoxBin2Prg esta terminado, está en etapa de mantenimiento, por lo que las ramas que se hacen son para corregir fallos e incorporar optimizaciones.


Trabajo en ramas cuando se trabaja en equipo


Cuando se trabaja en equipo, el desarrollo es similiar a trabajar en solitario, con la diferencia de que habrá una rama por cada desarrollador, y que en general los desarrolladores harán el merge en una rama de Integración, que en el ejemplo de la imagen de abajo es /main/TESTS, y en esa rama es donde irán integrando funcionalidades terminadas.

En esta rama de Integración no se deben subir cambios incompletos nunca, ya que esta rama debería ser lo bastante estable como para que el resto de desarrolladores puedan actualizar sus propias ramas desde la misma, con bastante seguridad en que no comenzarán a tener errores provocados por una subida inconclusa o errónea.

Convendría que se defina la figura del Integrador Principal, que sería la persona a cargo de hacer la revisión final del código que se integrará y los merge de las ramas de Integración en la rama principal una vez concluida la revisión. Esta figura es muy importante en el ciclo de desarrollo, ya que tiene la responsabilidad de integrar todos los desarrollos en la rama principal.

Durante esta revisión, el Integrador inspecciona las diferencias en el código de la rama de Integración (no en la rama de cada desarrollador!) usando la herramienta de Diff, para buscar posibles problemas o cosas mejorables y detectarlas antes de que se suban a la release definitiva en la rama Principal.


Pantallazo de un proyecto con su rama principal, su rama de Integración y dos desarrolladores Dev_1 y Dev_2:


Sobre esta forma de trabajar, ya había publicado un video.

Como puede verse en la imagen de arriba, cada desarrollador va trabajando en su rama y cuando tiene una funcionalidad terminada puede hacer una de dos opciones:

  • La integra con un merge en la rama de Integración, y acto seguido se actualiza su propia rama desde la de Integración para tener el trabajo de los demás. (Se puede ver que Dev_1 hizo esto en los dos primeros changesets)
  • O se baja primero lo de la rama de Integración en la rama propia con un merge y luego, con todo ya intgrado en su rama, hace otro merge en la rama de Integración desde la propia. (se puede ver que Dev_2 hizo esto en su segundo y tercer changeset)
Como recomendación personal, yo creo que la segunda forma de integrar es la mejor y más segura, ya que cada uno se está Integrando en la rama propia lo que hay en la rama de Integración, con lo cual si surgieran conflictos, se resolverían en la propia rama y no se afectaría a nadie si esto se hiciera mal. Además de que esto permite que una vez realizada esta actualización local se puedan probar los cambios integrados y corregir posibles errores antes de hacer el merge nuevamente en la rama de Integración, y así se tiene cierta seguridad sobre lo que se sube, ya que en el peor caso, si surgen errores en las pruebas locales (rama propia), nadie más estará afectado aunque se actualice desde la rama de Integración.

Si se hiciera al revés (merge a Integración y posterior merge a rama propia), se corre el riesgo de que se haga algo mal durante la Integración dejando esta rama inestable, y el problema es que, aunque se detecte en las pruebas posteriores, como esta rama es pública para el resto de desarrolladores, un error puede provocar que los demás que se actualicen se les propague a sus propias ramas antes de que se pueda corregir el error, lo que puede tomar un buen rato.



Trabajo en ramas con sistemas complejos y varios desarrolladores


Este escenario es similar al anterior, pero en este caso pueden haber varias ramas intermedias para distintas funcionalidades simultáneas, lo que crea un diagrama más complejo, y en el que la figura del Integrador Principal es imprescindible, ya que es quien debe conocer qué desarrollos deben integrarse en la versión actual o cuáles son para la próxima versión.

La siguiente imagen es una simulación de lo que puede ser un sistema complejo, formado por dos proyectos cortos, cada uno con dos desarrolladores, en los que se harán dos funcionalidades distintas que confluirán en la rama de Integración y de ahí a la rama principal en la versión etiquetada como v2.0, y de un proyecto a medio plazo, también con dos desarrolladores, que se va actualizando con la release principal, pero que todavía debe continuar desarrollando y por eso no hace merge en la principal.

(Click en la imagen para agrandar)


Cuando ese proyecto de mediano plazo se deba integrar, se deberá crear primero una nueva rama de Integración que salga de la última release disponible (por ej: de la v4.0), y deberá integrar sus cambios allí para poder realizar pruebas y certificar el funcionamiento, antes de que se integre en la rama Principal.



Recomendaciones finales


Como se ve, dependiendo del tipo de proyecto a realizar, el trabajo en ramas ayuda mucho si se usa adecuadamente. Dejo algunas recomendaciones para tener en cuenta, que están basadas en las buenas prácticas y en la experiencia de varios proyectos durante bastante tiempo:

  • En los componentes usar rutas relativas, nunca rutas absolutas. Esto permitirá que el proyecto sea portable e independiente de la ruta que se use para trabajar
  • Para un proyecto compartido conviene predefinir y usar el mismo directorio entre desarrolladores para evitar diferencias en el pjx, que si no a cada desarrollador le detectará un directorio distinto, el cuál aceptará y esto generará una nueva diferencia innecesaria
  • Hacer uso extensivo de las buenas prácticas de programación (encapsulación, refactorización, etc).
  • Como mínimo se debería respetar una nomenclatura de objetos, como la sugerida por la ayuda de FoxPro. Esto no solo permite que el código se auto-documente, sino que facilita los merge manuales y maximiza los automáticos que no requieren intervención
  • Usar FoxPro desde el directorio raiz del proyecto (workspace) y no cambiar la sesión a otros directorios (set default to <dir> o cd <dir>) ya que esto puede provocar problemas y bloqueos en el SCM cuando se quiera hacer un checkin o cambiar a otro changeset
  • Cerrar siempre los forms, proyectos, clases y programas abiertos, y hacer CLEAR ALL antes de ir al SCM a realizar alguna tarea.
  • Un bloqueo en algún archivo controlado por el SCM puede provocar un error en el checkin o que impida poder regenerar las versiones texto o binario con FoxBin2Prg y que en consecuencia se suban archivos des-sincronizados entre sí, como un binario sin su tx2 o viceversa

Hasta la próxima!


PlasticSCM: Agregando un proyecto FoxPro 9 al control de código fuente

Por: Fernando D. Bozzo

Es muy probable que tengamos proyectos que no están bajo control de código con un SCM, tanto porque sean antiguos proyectos, como porque consideramos que no ameritaban estar controlados o simplemente porque recién se está comenzando en este mundo del control de código.

Por el motivo que sea, tenemos uno o varios proyectos que queremos controlar con el SCM, así que vamos a ver un ejemplo de los pasos y configuraciones desde cero para hacerlo, asumiendo que que ya tenemos Plastic instalado y configurado.

Para el ejemplo voy a usar el proyecto FoxUnit, que es uno de los proyectos Open Source de VFPX en CodePlex para hacer Unit Testing (testing automatizado de código) que suelo usar frecuentemente, y que lo tengo en el directorio c:\desa\FoxUnit:



Como se puede observar en la captura anterior, hay archivos temporales, restos de pruebas y los archivos nos están normalizados (capitalizados), por lo tanto el primer paso es hacer esa normalización, usando click-derecho en el nombre del directorio de FoxUnit, y eligiendo la opción "Enviar a" y luego "Normalize_FileNames.vbs", que es uno de los scripts incluidos en las herramientas FoxPro 9 para Plastic.




Una vez ejecutado, los archivos quedan así:


Ahora que tenemos los archivos normalizados, vamos a crear un repositorio llamado FoxUnit, con un workspace llamado igual, ya que tanto el directorio como el proyecto ya se llaman así. La creación del repositorio y workspace ya los expliqué en el artículo de Instalación de Plastic, la única diferencia es que si Plastic ya está instalado y se quiere crear un nuevo repositorio y workspace (en ese orden), se deben seleccionar las opciones del pabel izquierdo, dentro de "Repositorios & Workspaces"




Hay dos archivos de configuración para Plastic que se deben crear en todos los proyectos que se quieran controlar, y que son "filetypes.conf" e "ignore.conf"


El archivo de configuración filetypes.conf


El archivo "filetypes.conf" sirve para indicarle a Plastic el tipo (texto/binario) de ciertos archivos que por no ser estándares pueden ser reconocidos incorrectamente. Por ejemplo, todas las extensiones texto de FoxBin2Prg, el config.fpw de FoxPro y algunas otras, por defecto se suelen reconocer como binarios. El tipo de archivo se puede ver en las vistas de Items y Cambios Pendientes, en la columna "tipo".

Para FoxPro, el filetypes.conf suele tener este contenido:

# PlasticSCM custom file types.
# Syntax: <extension>:<type>
# Type can be 'txt' or 'bin'.
# Examples:
#     .cpp:txt
#     .jpg:bin
.cfg_:txt
.cfg:txt

.fpw:txt
.prg:txt
.pj2:txt
.vc2:txt
.sc2:txt
.fr2:txt
.lb2:txt
.db2:txt
.dc2:txt
.mn2:txt


Este archivo puede estar a nivel de repositorio o a nivel del sistema. Si está a nivel de repositorio, se debe poner en la raíz del workspace, y si es a nivel del sistema, suele estar en el directorio <PerfilDelUsuario>\Configuración local\Plastic5
Si se pone a nivel del repositorio (lo recomendable), también es útil ponerlo dentro del control de código, para que los desarrolladores que se unan al proyecto tengan automáticamente la misma configuración y así no deben volver a hacerla cada vez.


El archivo de configuración ignore.conf


El archivo "ignore.conf" le indica a Plastic qué archivos no queremos ver en las vistas de Items y Cambios Pendientes. Es un filtro visual, y al igual que el filetypes.conf, puede estar a nivel de repositorio o de sistema, y en las mismas ubicaciones ya comentadas.


Para FoxPro, el ignore.conf suele tener este contenido:

*.FXP
*.LNK
!/_iniciar aqui.lnk
*.SCC
*.TMP
*.BAK
*.ZIP
*.7Z
*/FXUResults.*
*/FXUPersist*.*
.plastic
.git


Es importante conocer su sintaxis, ya que permite hacer cosas muy útiles como ocultar ciertas extensiones pero mostrarlas en un directorio particular. La sintaxis permite indicar:
  • Una extensión (ej: .fxp)
  • Un archivo (ej: foxuser.dbf)
  • Un archivo en una ruta específica relativa a la raíz del workspace (ej: /forms/unarchivo.xml)
  • Un directorio (ej: .git)
  • Una negación de las reglas generales que se aplicarán a un archivo en una ruta específica (ej: !/_Iniciar aqui.lnk)

Importante: Notar que las barras de directorio no son las de Windows (\), sino el símbolo dividido (/)

Este archivo también se puede actualizar desde la GUI de Plastic, en la vista de Items y de Cambios Pendientes, haciendo click-derecho sobre un archivo y eligiendo "Añadir a la lista de cambios ocultos" donde se mostrarán 3 opciones:
  • archivo.ext
  • .ext
  • /ruta_absoluta/archivo.ext

Agregar el proyecto FoxPro a control de código


Al fin, ya tenemos todo preparado, configurado y normalizado para agregar el proyecto, por lo que regeneramos las vistas de texto, regeneramos los binarios, agregamos el README.txt y posteriormente agregamos todos los archivos relevantes, es decir, todos menos los archivos temporales o archivos de pruebas que no formen parte del proyecto:



Generación de los archivos de texto (tx2):



Agregado del README.txt:


Checkin del README.txt con un comentario:



El Explorador de ramas muestra el segundo changeset (el primero siempre es vacío):




Agregado el control de código de los archivos del proyecto y los tx2 generados:



Comentario de checkin y checkin final:



El Explorador de ramas muestra el tercer changeset (al anterior es el README.txt y el primero siempre es vacío):


Y ya está. A partir de aquí es crear ramas para comenzar a trabajar en ellas.


Hasta la próxima! =)

viernes, marzo 07, 2014

PlasticSCM: Hice un checkin erróneo de un archivo nuevo ¿cómo lo arreglo?

Por: Fernando D. Bozzo

A todos nos puede pasar que estamos trabajando en algo, y en un momento dado queremos proteger los cambios, entonces vamos al SCM, elegimos los archivos y hacemos checkin.... pero luego nos damos cuenta de que cometimos un error, ¿cómo lo arreglamos?

   Si el error detectado es de capitalización de un archivo recién agregado, pero al cual todavía no hicimos checkin, es muy fácil: Ir a la ventana de Cambios Pendientes y seleccionar el botón "Deshacer cambios". Problema resuelto, se soluciona el problema de capitalización haciendo la conversión texto/binario que ya comenté en el punto 3 y 4 de la otra nota, y se repite el proceso de agregar el archivo.

   Si el error detectado es de capitalización de un archivo agregado y que además se le hizo checkin, entonces habrá que hacer una copia del mismo (en un zip por ejemplo) y eliminar el último changeset creado, así:


1) Seleccionamos el changeset anterior con click-derecho:


2) Elegimos la opción "Apuntar workspace a este changeset":



2.b) ¿Muestra un error?: Si les muestra un error como el de la imagen, pueden elegir entre las opciones que ven en la imagen, y que ahí mismo están explicadas:




3) Hacemos click-derecho en el changeset a borrar (siempre es el último) y elegimos "Borrar changeset":


4) Y listo, el changeset fue borrado y el nuevo changeset actual es el anterior:


5) Finalmente, como se ha borrado un changeset que en este caso consistía en archivos agregados al SCM, esto implica que Plastic los borrará del directorio de trabajo, y por eso hicimos el ZIP en un paso anterior. Simplemente se vuelven a descomprimir los archivos, se procesan con FoxBin2Prg (solo si son binarios Fox) pasándolos a texto y binario nuevamente, se comprueba la capitalización y se vuelven a agregar al control de código.


Esto también se puede hacer cuando se protege un cambio que no se quiere guardar, pero lo ideal es solo hacer el checkin cuando se tiene certeza de que lo que se sube es correcto.


Video de ejemplo:

FoxPro 9: Deshacer Merge de 2 ramas en PlasticSCM




Importante:
Para evitar estos inconvenientes, es mejor verificar visualmente la capitalización de los archivos justo antes de que se vayan a proteger, y no olvidar que cualquier form, clase, etc, que se haya modificado, se debe pasar primero a texto y luego del texto se debe pasar a binario otra vez, ya que en estos pasos también se hace el ajuste de la capitalización.

Otra cosa a estar atento es no subir cualquier archivo, es decir, el control de código fuente (SCM) es justamente para eso, para controlar los archivos de programa que hacemos, y no para proteger los archivos temporales (tmp) o los backup (bkp) u otro tipo de archivos que no tienen nada que ver con nuestro desarrollo.

Incluso es conveniente guardar la versión texto de las tablas (archivos DB2) y bases de datos (archivos DC2) generados con FoxBin2Prg, pero no guardar las tablas con datos, porque si no el espacio destinado para el código se agotaría bastante rápido. Recordar que todo esto se guarda en una base de datos de Plastic que se puede elegir entre la que viene por defecto  y que sirve para pequeños desarrollos o desarrollos personales (SQL Server CE - 4 GB por repositorio/proyecto), u otras bases de datos más potentes como SQL Server full, MySQL, Oracle u otras.


Nota Relacionada:
FoxPro 9 y PlasticSCM: Como deshacer un changeset sin borrarlo




jueves, marzo 06, 2014

PlasticSCM: Cómo crear una rama para comenzar a trabajar

Por: Fernando D. Bozzo

En esta nota vamos a ver cómo crear una rama en PlasticSCM, pero antes de hacerlo es necesario saber qué es un rama.
Antiguamente se usaban directorios para crear copias del sistema o de ciertos componentes con determinados cambios. Por ejemplo, si se tiene un form con una pageframe y una página, se agrega otra página y se quería guardar ambas versiones por las dudas, entonces se creaba un directorio para la versión de 1 página y otro directorio para la versión de 2 páginas, y en cada uno se copiaban los forms correspondientes.

Esto tiene el inconveniente de que no es práctico, la cantidad de directorios y copias va creciendo y es fácil perderse entre tantas copias. Además que no hay forma de mezclar los cambios de un directorio con los de otro.


Las ramas

Una rama se usa para lo mismo que se usaban los directorios con distintas versiones, mantener una serie de modificaciones relacionadas a uno o varios componentes. Qué parámetro se use para establecer esa relación puede variar para cada uno, pero lo ideal es tener una rama por usuario y por tarea, ya que la idea es no trabajar nunca sobre la rama principal directamente, hacerlo siempre sobre ramas independientes.


El changeset (o "juego de cambios")


En Plastic el icono de la casa indica un punto en la historia de modificaciones que fueron guardadas con check-in y es el equivalente a lo que antes era el directorio con una copia con cierta modificación particular, por eso es importante hacer un check-in cada vez que se  complete alguna funcionalidad, y antes de pasar a la siguiente.

Para seleccionar un "changeset" se hace click-derecho en el changeset al que se quiere ir, y se elige la opción "Apuntar workspace a este changeset", o sea, se cambia el área de trabajo a ese punto de la historia del proyecto.

Pero, ¿qué ocurre cuando se cambia de changeset realmente? Lo voy a explicar con directorios.
Imaginen que tienen un directorio llamado "c:\mi_sistema_actual" que contiene 3 archivos:

c:\mi_sistema_actual => a.txt, b.txt y c.txt

Ahora se cambian a una copia más vieja que llamaron "c:\mi_sistema_feb_2012" donde solo había 2 archivos:

c:\mi_sistema_feb_2012 => a.txt y b.txt

El archivo c.txt no existe aquí porque fue agregado más recientemente en "c:\mi_sistema_actual", entonces al cambiarse a este directorio es lógico no ver ese archivo, pero si nos volvemos a cambiar al otro, entonces sí que lo vemos.

Pues en Plastic es parecido, pero ocurre todo esto en el directorio que se ha elegido como "workspace", y recalco lo de "espacio de trabajo" porque durante toda la vida del proyecto, todos los cambios se harán en este directorio o workspace. Lo que hace Plastic es "reemplazar" los archivos "controlados" por los archivos del changeset que elijamos, borrando del workspace (directorio) los archivos "controlados" del changeset actual y descargando del servidor los archivos "controlados" del changeset elegido.

No hay que asustarse cuando hablo de "borrar", ya que esto solo lo hace con los archivos que sabe que luego puede recuperar, y por eso los archivos "no controlados" se llaman "privados" y no se tocan. Los archivos privados para Plastic es como si no existieran, aunque los muestra en la ventana de items para que podamos agregarlos al control de código si queremos, y que desde ese momento cambien al estado de "controlados".


Creando una rama


Vamos a crear una rama para que cada uno pueda realizar sus pruebas o su trabajo, y no entre en conflicto con lo que hagan los demás desarrolladores.
Como origen de esta rama se debe seleccionar el changeset desde el cuál se quiere partir, que en general es el último, pero también puede ser otro anterior.


1) Abrimos la vista del Explorador de Ramas (panel izquierdo), hacemos click-derecho en el changeset elegido para bifurcar y seleccionamos "Crear rama desde este changeset"


Figura 1


2) Luego le damos un nombre a la rama. Normalmente este nombre debería ser el de la tarea que se comenzará, algo como "nuevo-form-articulos", "petición-02332" o "tarea-nnn", pero para el caso de las prácticas que estamos haciendo lo voy a nombrar como "usuario" donde cada uno debe reemplazar "usuario" por su usuario:


Figura 2


3) Finalmente podemos ver la nueva rama con la casita, ya que en la pantalla anterior estaba marcado por defecto la opción "Apuntar workspace a esta rama":

Figura 3


Y ahora sí, teniendo cada uno su propia rama, se puede comenzar a trabajar en la tarea, lo que normalmente es abrir una sesión de FoxPro en el directorio del workspace y comenzar a trabajar.



Comprobación de la ruta de nuestra rama


Cuando se crea una rama, queda una flecha gris señalando el origen de datos de la misma, que en este caso coincide con el changeset de origen, y el panel derecho muestra su ruta completa:

Figura 4


Cuando se crea una rama de otra que todavía no tiene nada nuevo, la flecha gris sigue señalando el origen de datos de la misma, pero en este caso el origen de datos no coincide visualmente con el changeset del ejemplo anterior elegido para hacer la rama, lo que puede confundir inicialmente, pero si observamos en el panel derecho, la ruta es correcta a pesar de lo que marca la flecha gris:

Figura 5


Una vista útil para esto es la llamada "Ramas" (panel izquierdo), donde se muestra la relación entre las ramas en forma de texto, y se resalta en negrita la actual (que en la vista anterior muestra el icono de la casa).

Desde esta vista también se pueden crear sub-ramas, y en algunos casos en los que en el Explorador de Ramas no se puede clickear o seleccionar la rama buscada, por ejemplo, por estar tapada por otra, esta es la única forma de poder hacerlo sin equivocarse.

Figura 6


Bueno, ya es hora de practicar un poco!


En este punto les puede interesar:
FoxPro 9: Creando un componente y añadiéndolo al control de código PlasticSCM
FoxPro 9 y PlasticSCM: Como deshacer un changeset sin borrarlo

(Sigue en: "PlasticSCM: Hice un checkin erróneo de un archivo nuevo, ¿cómo lo arreglo?")