Selectores en Plastic SCM: Bienvenidos al lado oscuro II

10:03 0 Comments

¡Bienvenidos de nuevo al lado oscuro de Plastic! Hoy nos vamos a adentrar más en conceptos de ramas e intentaremos explicar como funcionan las ramas y las etiquetas.

En el post anterior introduje diversos conceptos importantes tales como que plastic evalua una por una las reglas del selector, de arriba hacia abajo, y cómo funciona el especificador de la ruta.

Veamos ahora el modificador de la regla del selector de etiquetas. Pero antes de nada, ¿qué es una etiqueta?

Una etiqueta es simplement un objeto dentro de un repositorio de Plastic. Tan sólo eso. Al crear una etiqueta desde la línea de comandos o desde la interfaz gráfica simplemente se crea un nuevo objeto dentro del repositorio.

Las etiquetas son muy útiles una vez que se aplican a las revisiones como se puede ver en el siguiente árbol de versiones. En el árbol se puede ver que la revisión 20 tiene sólo una etiqueta, BL051, pero la revisión 19 tiene muchas (lo cual en este ejemplo significa que pertenece a diversas líneas base...no se ha cambiado en bastante tiempo).





Así que para etiquetar una revisión en Plastic primero hay que tener una etiqueta y entonces aplicar la etiqueta a la revisión. Desde la interfaz gráfica la única opción disponible es etiquetar todo el contenido del espacio de trabajo, lo que significa aplicar la etiqueta a las revisiones que están cargadas en ese momento. ¿Por qué? Porque los usuarios normalmente utilizan etiquetas para agrupar un conjunto de revisiones en momentos específicos como puede ser el caso de sacar una nueva versión. Y normalmente lo que se desea etiqueta es todo el espacio de trabajo.
Veamos el ejemplo de la siguiente figura.



Se puede ver que tenemos un directorio con un par de entradas, una de ellas etiquetada con la etiqueta "BL001". Así que, ¿qué se cargará en el espacio de trabajo si se configura el siguiente selector?


rep "default"
path "/"
label "BL001"



Le estamos diciendo a plastic:
descarga todo lo que esté marcado con BL001. Así que, ¿qué es lo que esperamos que se descargue?

¡Nada!

Obtendremos un error que dirá que no se puede cargar el ítem raíz.

¿Por qué? Bueno, recordemos cómo Plastic resuelve los selectores: primero coge el ítem raíz y busca una revisión utilizando las reglas de los selectores. Así que intentará encontrar una revisión para el ítem raíz etiquetada con BL001 y... si, no puede... se terminó.

Así que, o se etiqueta el ítem raíz también, o se proporciona una regla que cargue la raíz.


rep "default"
path "/"
label "BL001"
path "/"
branch "/main"


Este selector resuelve el problema.Irá a la segunda regla para encontrar la revisión del ítem raíz, con lo que el problema está resuelto.

Ahora entenderéis por qué es tan peligroso el etiquetar revisiones separadas en vez de todo el espacio de trabajo, a no ser que se sepa muy bien lo que se está haciendo.

Las etiquetas son muy útiles ya que proporcionan una gran flexibilidad. En el siguiente ejemplo si se especifica un selector como el anterior se cargará el árbol del espacio de trabajo como el de la parte inferior de la figura.



Entra en el mundo de las ramas
Hasta ahora hemos jugado con revisiones, changesets y ramas. Empecemos a hablar de las ramas.

En plastic una rama es un contenedor de revisiones. Al crear una nueva rama se crea un objeto vacío en un repositorio. Hay que trabajar con ella para darle contenido. Tengan en cuenta que este comportamiento varía del de otros sistemas como Subversion, CVS, SourceSafe, TeamSystem orPerforce, en los que la creación de ramas conlleva copiar las revisiones a la nueva rama.

En plastic, cuando se crea una nueva rama, está totalmente vacía.

¿Cómo se puede utilizar? Supongamos que acabamos de crear una rama main/task001. La creamos desde la línea de comandos:


$ cm mkbr br:/task001


Tener en cuenta que desde la interfaz gráfica normalmente sólo se crean ramas hijas.

Hablaremos de las ramas hijas más adelante.

Bien, ahora tenemos task001, pero, ¿qué podemos hacer con ella?

Ahora ya son casi expertos en selectores, ¿tienen alguna idea?

Qué pasa si configuramos un selector como el siguente:


rep "default"
path "/"
branch "/task001"
co "/task001"


Si, así es...

El servidor dirá que no puede cargar el ítem raíz.

Así que hay que encontrar el modo de que llegue a la rama de la tarea task001...

¿Y la siguiente configuración?


rep "default"
path "/"
branch "/task001"
path "/"
branch "/main"


Bien, funcionará.


Pero estamos cargando las revisiones desde main... ¿Cómo puedo crear una revisión en la nueva rama?


rep "default"
path "/"
branch "/task001"
co "/task001"
path "/"
branch "/main"
co "/task001"

Mirad el selector de arriba. Especialmente la segunda regla.

Está diciendo a plastic: descarga las revisiones de main, pero si hay que desproteger algo... coloca la desprotección en "/task001". Así que, tan pronto como se desprotega un fichero o un directorio... irá a task001, y comenzaremos a utilizar la rama recién creada.

Por favor, tengan en cuenta que si la segunda regla es algo como ruta "/" rama "/main" co "/main" la revisión nunca irá a la tarea task001... así que la primera regla será inútil.

Ahora se ha realizado la primera desprotección en una rama separada... Si se ejecuta un ls desde línea de comandos o si se comprueba la vista de items desde la interfaz gráfica se podrá ver que la revisión está en una rama.

Hay dos cosas importantes aquí:
  • ahora tenemos un mejor entendimiento sobre los selectores
  • ahora entendemos como funcionan las ramas en plastic: este es exactamente el motivo por el que sólo las revisiones cambiadas van a las ramas mientras que el resto se mantienen en la rama padre...

    Ramas y etiquetas combinadas
    Con lo que hemos visto hasta ahora... ¿cómo se implementaría un patrón de rama por tarea?

    Fácil, simplemente se crea una nueva rama para cada nueva tarea, y se configura el selector como el de arriba. ¡Y ya está!

    "Bien" - puedes preguntar - "pero ¿qué pasa si necesito empezar a trabajar desde una línea base específica?".

    Veamos.

    Supongamos que queremos trabajar en la tarea task001, pero el punto de partida debe de ser una línea base estable etiquetada BL059.

    ¿Cómo configuraríamos el selector?

    Recordad: hay que coger todo de la BL059, a no ser que tengamos algo en la rama de la tarea que tengamos que descargar antes...

    Miren el siguiente selector.


    rep "default"
    path "/"
    branch "/task001"
    co "/task001"
    path "/"
    label "BL059"
    co "/task001"

    Bien, ¿no?


    Entonces, ¿para qué son las ramas hijas?

    Si pensáis que no son necesarias... es que sois unos verdaderos hackers del selector. ¡Enhorabuena! :-)

    Volvamos al selector referentes a las ramas /main y /task001


    rep "default"
    path "/"
    branch "/task001"
    co "/task001"
    path "/"
    branch "/main"
    co "/task001"

    ¡Aquí está!


    Después de unas cuantas semanas utilizandolas para seguir el patrón rama por tarea al principio del proyecto (hace mucho, mucho tiempo), obtenemos lo siguiente:

    ¿que pasa si hacemos que /task001 herede de /main de algún modo? Es lo que estamos intentando hacer con el selector...

    ¡Y entonces aparecen las ramas hijas!

    Si se crea la tarea task001 como hija de main, se dice que si la tarea task001 tiene contenido, toma sus revisiones de ella, de otro modo las tomaría de main que es exactamente lo que aparece en el selector anterior.

    Pero las ramas hijas hacen que la vida sea más fácil. Para crear una rama hija se puede ir a la interfaz gráfica o a la línea de comandos y ejecutar


    $ cm mkbr br:/main/task001

    Entonces el selector que se utilizará será:


    rep "default"
    path "/"
    br "/main/task001"
    co "/main/task001"

    ¡Que realmente ahorra dos líneas!.

    Y este es básicamente el motivo por el que las rama hijas aparecieron en escena: para ahorrar líneas al escribir el selector. (En este punto hay que tener en cuenta que cuando se incluyeron las ramas hijas los selectores aún se escribían en formato XML, esto fué en la prehistoria de plastic, antes de que cualquier cliente hubiese oído hablar de nosotros...y el ahorrar unas líneas es muy importante para los desarrolladores perezosos).

    Ramas hijas y etiquetas

    "Bien" - diréis - "pero qué ocurre si quiero utilizar una línea base, que es la manera normal de trabajar de todos modos..."

    ¡Y es cierto!

    Para utilizar una línea base se combina la regla de la etiqueta dentro de la regla de la rama, como en el caso del siguiente selector


    rep "default"
    path "/"
    br "/main/task001" label "BL051;LAST"
    co "/main/task001"


    Para acortar la regla de la etiqueta se puede simplificar:



    rep "default"
    path "/"
    br "/main/task001" label "BL051"
    co "/main/task001"


    Lo bueno es que es muy sencillo escribir selectores para múltiples ramas


    rep "default"
    path "/"
    br "/main/release50/bug-fix490" label "stable040;BL050;LAST"
    co "/main/release50/bug-fix490"

    La regla de rama por tarea

    Y ahora veamos una de las reglas del selector de plastic menos conocidas:


    rep "default"
    path "/"
    branchpertask "/main/task001" baseline "BL009"


    Que equivale a:


    rep "default"
    path "/"
    branch "/main/task001" label "BL009"
    checkout "/main/task001"


    ¡Pero incluso más corto

    ¡En resumen!

    Ahora ya estáis familiarizados con todos los conceptos internos del selector y listos para saltar al siguiente tema: ¡selectores de múltiples repositorios!
  • 0 comentarios: