<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">

<book lang="es">
    <bookinfo>
		<date>18 Agosto 2003</date>
		<title>Uso practico de CVS para control de versiones</title>
		<subtitle>Conceptos y practicas recomendadas</subtitle>
		<authorgroup>
			<author>
			<firstname>Franco</firstname>
			<othername>M.</othername>
			<surname>Catrin L.</surname>
			</author>
		</authorgroup>
		<address>fcatrin@tuxpan.com</address>
		<copyright>
			<year>2003</year>
			<holder>4to Encuentro Nacional de Linux</holder>
		</copyright>
		<revhistory>
			<revision>
			<revnumber>1.0</revnumber>
			<date>25-02-2003</date>
			<authorinitials>FCL</authorinitials>
			<revremark>Primera version</revremark>
			</revision>
		</revhistory>
    </bookinfo>
	<chapter>
		<title>Resumen</title>
		<para>El control de cambios es necesario para el desarrollo
			de cualquier tipo de proyectos de software.  La herramienta mas utilizada 
			para esta labor en proyectos Open Source es CVS (Concurrent Version System).
			Este documento presenta	los conceptos basicos de CVS, asi como tambien 
			caracteristicas avanzadas y	practicas recomendadas para su efectiva utilizacion.</para>
	</chapter>
    <chapter>
		<title>Introduccion</title>
		<para>El desarrollo de software no es una tarea exclusivamente individual.
			En la gran mayoria de los proyectos tanto Open Source como privados es necesario
			trabajar en equipos en donde son varios los desarrolladores que acceden
			al mismo codigo fuente.</para>
		<para>Coordinar las modificaciones concurrentes al codigo de una forma manual
			es una tarea titanica, sobre todo en proyectos muy complejos o con una gran
			cantidad de desarrolladores.</para>
		<para>Uno de los objetivos de CVS es proveer una herramienta que permita
			mezclar distintos cambios al codigo para consolidar un codigo unico final
			de una forma automatizada, siempre que sea posible.</para>
		<para>Otro de las funciones que cumple una herramienta como CVS es mantener
			un registro de los cambios que se hacen al codigo fuente.  De tal forma que se
			tenga acceso a todo el historial de cambios del proyecto.  Esta caracteristica
			permite volver a versiones anteriores, encontrar defectos introducidos y mantener
			un mismo proyecto en una version "estable" y "en desarrollo" a partir de un 
			solo repositorio comun.
		</para>
		<para>Estas capacidades son de vital importancia en proyectos Open Source, en donde
			los desarrolladores estan separados geograficamente y temporalmente.  Sin
			embargo las mismas practicas son tambien aplicables a proyectos privados.</para>
	<sect1>
		<title>Arquitectura de CVS</title>
		<para>CVS es una herramienta que funciona en un esquema de cliente y servidor.
			Existe un cliente o estacion de trabajo en donde los desarrolladores hacen 
			modificaciones al codigo y realizan las pruebas necesarias para satisfacer
			los requerimientos.
			En el servidor existe una version consolidada del proyecto.  Cada cierto tiempo
			los desarrolladores actualizan sus versiones de trabajo desde el servidor
			y por otra parte envian sus propios cambios hacia el servidor.</para>
		<para>Existen servidores para Linux y Unix, asi como clientes para una extensa
			gama de plataformas (Linux, Windows, MacOSX, etc).</para>
		<para>Uno de los beneficios de este esquema, es que se puede integrar la
			funcionalidad de cliente CVS en las herramientas de desarrollo integradas (IDE).
			En la plataforma Linux es comun que se realice esta integracion, debido a lo
			fundamental que se ha convertido CVS en la mayoria de los proyectos que
			integran esta plataforma, incluyendo los mismos proyectos de desarrollo de estos IDE's.
			Es asi como por ejemplo podemos encontrar KDevelop de KDE, Anjuta y Eclipse en GNOME
			integrados (y desarrollados) con CVS</para>
	</sect1>
	<sect1>
		<title>Forma de trabajo basica</title>
		<para>Cada archivo que compone el proyecto puede ser modificado por varios 
			desarrolladores al mismo tiempo en forma independiente.  CVS se encarga de
			consolidar los distintos cambios en un solo archivo final que incluya todos
			los cambios introducidos por los distintos desarrolladores.</para>
		<para>Existe solo un caso especial en donde mas de un desarrollador puede
			introducir cambios en la misma parte del codigo.  Esto se conoce como conflicto.
			Es tarea del usuario que produce el conflicto, resolverlo y enviar una version
			consolidada al servidor</para>
		<para>Cada archivo tiene un numero de revision independiente.  Este numero
			registra el numero de cambios hechos al archivo y no tiene ninguna relacion
			con algun numero de version del proyecto completo.  Mas adelante se vera como
			se pueden manejar los archivos almacenados en CVS como un conjunto</para>
	</sect1>
	<sect1>
		<title>Limites de CVS como herramienta</title>
		<para>CVS como herramienta no resuelve todos los problemas del desarrollo
			en equipo.  Simplemente es una ayuda para que las cosas mas tediosas
			puedan ser automatizadas.</para>
		<para>Las areas en donde CVS no esta involucrado tienen relacion con
			el tratamiento del proyecto a un nivel global.  Actividades como la
			planificacion, los releases, etc, quedan fuera de su ambito de trabajo
			y deben ser abordadas por las personas y otras herramietnas complementarias</para>
	</sect1>
	</chapter>
	<chapter>
	<title>Uso basico de CVS</title>
	<para>CVS es una herramienta bastante flexible, no es necesario utilizar todas
		las caracterisitcas que posee, pero si al menos se debe tener conocimiento
		de las operaciones mas elementales para comprender las funcionalidades
		mas avanzadas y que son de interes en este trabajo.</para>
	<sect1>
	<title>Repositorio</title>
	<para>
		En la parte de servidor de CVS se maneja un repositorio.   Un repositorio es simplemente un
		directorio en el servidor que contiene diversos modulos.  Por ejemplo, un proyecto podria
		tener un repositorio, y en cada modulo estarian los subproyectos.</para>
	<para>A su vez, cada modulo contiene un conjunto de archivos, y representa al proyecto con
		el que se quiere trabajar.  Por ejemplo en sitios grandes como sourceforge, cada uno
		de los proyectos tiene su propio repostorio CVS, y cada uno de ellos tiene uno o mas
		modulos de trabajo.  Cuando un desarrollador trabaja con CVS lo hace a nivel de modulo.</para>
	<para>Para conectarse al servidor se pueden usar distintos tipos de protocolos, sin embargo
		los mas extendidos son "pserver" para acceso anonimo o algun tipo de acceso en donde
		la seguridad no es importante. El otro es ssh, y se usa en casos mas criticos,
		por ejemplo cuando se requiere acceso para poder realizar cambios al repositorio.</para>
	<para>Para que un directorio pueda ser utilizado como repositorio CVS, lo primero que se
		debe hacer es decirle a CVS que genere los archivos y subdirectorios necesarios para
		funcione como tal.  Podriamos crear un repositorio con los siguientes comandos:</para>
	<para>Primero creamos un grupo especial para que pueda hacer cambios en CVS</para>
	<screen><prompt>
[root@shaman root]# groupadd cvs
	</prompt></screen>
	<para>Luego se crea un directorio para almacenar el repositorio</para>
	<screen><prompt>
[root@shaman root]# cd /usr/local/
[root@shaman local]# mkdir cvs-utfsm
	</prompt></screen>
	<para>Se indica a CVS que inicialice el directorio recien creado</para>
	<screen><prompt>
[root@shaman local]# cvs -d /usr/local/cvs-utfsm init
	</prompt></screen>
	<para>Se actualizan los permisos para que los usuarios del grupo CVS efectivamente tengan 
	control sobre el repositorio</para>
	<screen><prompt>
[root@shaman local]# chown root.cvs -R cvs-utfsm
[root@shaman local]# chmod 775 cvs-utfsm
	</prompt></screen>
	<para>Como resultado se obtendra un directorio CVSROOT al interior de cvs-utfsm. Este directorio
		contiene los archivos necesarios para que CVS lo trate como un repositorio</para>
	</sect1>
	<sect1>
	<title>Modulo</title>
	<para>Un modulo contiene un grupo de archivos que se administra de manera conjunta.
		Por ejemplo, cada vez que se realiza alguna actualizacion a nivel de conjunto de
		archivos, el ambito sera de un modulo.</para>
	<para>Cada repositorio puede tener un numero indefinido de modulos, Se sugiere siempre
		tener los archivos relacionados con un modulo de software bajo un unico directorio.
		De esta forma, habra una correspondencia univoca entre el modulo de software y
		un modulo CVS.</para>
	<para>Para comenzar a trabajar en un modulo a partir del repositorio de ejemplo que
		se ha creado, lo primero que debemos hacer es importarlo.  En este ejemplo
		se usará una conexion SSH hacia el servidor (aunque sea local).</para>
	<para>El primer paso es definir una variable de entorno que para indicar que el
		protocolo a usar es SSH.</para>
	<screen><prompt>
export CVS_RSH=ssh
	</prompt></screen>
	<para>Luego se define una variable de entorno para indicar el repositorio que se usara.
		Esto solo es necesario hacerlo cuando aun no estamos trabajando con ningun modulo.</para>
	<screen><prompt>
export CVSROOT=:ext:fcatrin@localhost:/usr/local/cvs-utfsm
	</prompt></screen>
	<para>La variable de entorno CVSROOT tiene distintas secciones separadas por ":".  La
		primera seccion es el protocolo, en este caso ext indica RSH o lo definido por
		la variable CVS_RSH.</para>
	<para>La segunda seccion indica en nombre de usuario con que se accedera al repositorio
		y el host que lo contiene.  Finalmente se indica el directorio del repositorio.</para>
	<para>Ahora se puede importar el directorio actual de trabajo en el repositorio
		A modo de ejemplo se usara un directorio test contenido en el home del usuaro.</para>
	<screen><prompt>
cd ~/test
cvs import test fcatrin start
	</prompt></screen>
	<para>Este comando crea un modulo llamado test en el repositorio (CVSROOT) usando
		los contenidos del directorio de trabajo test.  Para comenzar a trabajar con
		este directorio se ejecuta:</para>
	<screen><prompt>
cd ~
mv test test-sincvs
cvs co test
	</prompt></screen>
	<para>Cuando un directorio se importa como modulo a CVS, las modificaciones solo se
		realizan en el servidor y el directorio queda tal como estaba en un principio,
		sin ninguna relacion con CVS.</para>
	<para>Lo que se hizo fue mover el directorio original a otro sitio y luego efectuar
		una operacion Checkout desde nuestro modulo test recien creado en el repositorio
		indicado por CVSROOT.</para>
	<para>El directorio test volvera a ser creado y contendra un subdirectorio de
		control llamado CVS en donde se encuentra la informacion acerca del modulo
		correspondiente en el repositorio.</para>
	<para>A partir de este momento, ya no sera necesario usar la variable CVSROOT al
		trabajar con este modulo de trabajo, ya que la informacion de conexion al
		repositorio estara en el archivo CVS/Root, en el directorio de trabajo.</para>
	</sect1>
	<sect1>
		<title>Trabajo basico con CVS : update y commit</title>
		<para>El uso basico de CVS se remite a un pequeño numero de tareas,
			orientadas principalmente a mantener sinronizado el servidor con la
			version de trabajo (cliente) y viceversa.</para>
		<para>A partir de un modulo que ya existe en nuestro disco, obtenido a traves
			de la operacion de Checkout (co) indicada en la seccion anterior, podremos
			comenzar a realizar cambios sobre nuestro software.  Los cambios seran
			registrados en el servidor cuando se considere conveniente.  De la misma
			forma los cambios realizados por otras personas en el servidor seran
			mezclados en nuestra copia local cuando se desee.</para>
		<para>La primera operacion basica sobre nuestra copia local es la
			actualizacion.  Esta operacion revisara que archivos han sufrido cambios
			en el repositorio respecto a nuestra version de trabajo.  Aquellos cambios
			seran aplicados a la version local, mezclandose con nuestros propios
			cambios.  Tambien podemos indicarle a CVS que genere localmente todos los
			archivos y directorios que hayan sido creados recientemente por otros
			desarrolladores.</para>
	<screen><prompt>
cd ~/test
cvs update -dP
	</prompt></screen>
		<para>Como resultado del comando se vera un listado con cada archivo contenido
			en el directorio de trabajo. Antes de cada nombre de archivo aparecera
			un caracter indicando que operacion se realizo:</para>
		<itemizedlist>
			<listitem><para>? : Se desconoce el archivo en el repositorio (no hace nada).</para></listitem>
			<listitem><para>A : Ha sido agregado localmente, pero aun no existe en el repositorio.</para></listitem>
			<listitem><para>D : Ha sido eliminado localmente, pero aun existe en el repositorio.</para></listitem>
			<listitem><para>M : Ha sido modificado localmente y/o mezclado con el del repositorio.</para></listitem>
			<listitem><para>U : Archivo agregado en el repositorio se ha creado localmente.</para></listitem>
			<listitem><para>C : Hay un conflicto entre los cambios locales y los del repositorio.</para></listitem>
		</itemizedlist>
		<para>El unico caso preocupante es un conflicto.  Como consecuencia de el, en el
			codigo quedara una seccion marcada como conflicto en donde apareceran dos
			versiones.  En una estaran los cambios realizados localmente, y en la otra
			los cambios realizados remotamente.  El usuario debe resolver este conflicto
			editando el archivo para dejar la version final.</para>
		<para>Cuando ya se han realizado todos los cambios necesarios, se deben subir
			al repositorio estos cambios.  Esto se realiza con la operacion Commit (ci)
			que puede operar sobre un grupo de archivos o sobre el modulo completo.</para>
		<para>Al realizar un commit es obligatorio dejar un mensaje explicativo para
			que quede registrado junto al cambio en CVS.  Esto es muy util para obtener
			un historial de cambios al proyecto.  Para poner el mensaje se debe usar
			la opcion -m</para>
		<para>Ejemplos de commit:</para>
	<screen><prompt>
cvs ci -m "Solo cambios a un solo archivo" archivo.c
cvs ci -m "Cambios globales"
	</prompt></screen>
		<para>El primer ejemplo solo actualiza el "archivo.c", el segundo ejemplo
			actualiza el modulo completo.</para>
		<para>Puede darse el caso de que existan revisiones mas nuevas de los archivos
			modificados.  Ese caso aparecera un error de "up-to-date failed" en el
			cliente y debera realizarse un update en el repositorio local, antes de
			poder efectuar el commit.</para>
		<para>En el ciclo de vida de un proyecto de software, la mayor parte del tiempo
			solamente sera necesario usar commandos de update y commit.</para>
	</sect1>
	<sect1>
		<title>Agregando y eliminando archivos</title>
		<para>Otras operaciones basicas son la agregacion y eliminacion de archivos
			al repositorio.  En un principio, CVS manejara todos los archivos existentes
			al momento de realizar la operacion de import del directorio en el repositorio.
			A partir de ese momento, cualquier cambio en los archivos manejados por CVS,
			por ejemplo agregar y/o eliminar, debera realizarse de forma explicita.</para>
		<para>Para agregar un archivo se debe utilizar la operacion "add" sobre el archivo
			o directorio.  Los archivos quedaran marcados para agregacion, pero esta operacion
			solo se hara efectiva al momento de hacer un commit.</para>
		<para>Para eliminar un archivo, primero debe eliminarse fisicamente del directorio,
			luego se usa la operacion "remove" sobre el nombre del archivo y este quedara
			marcado para su eliminacion en CVS.  Al igual que "add", la operacion se hara
			efectiva al hacer commit.</para>
		<para>En el siguiente ejemplo se agregara el archivo nuevo.c y se eliminara
			el archivo antiguo.c:</para>
	<screen><prompt>
cvs add nuevo.c
rm antiguo.c
cvs remove antiguo.c
cvs commit
	</prompt></screen>
	</sect1>
	<sect1>
		<title>Obtencion de diferencias entre repositorio y version local</title>
		<para>A veces es necesario conocer que cambios se han realizado a nivel local
			o en el repositorio.  Por ejemplo para auditar nuestros propios cambios o para
			revisar los cambios que se integrarian en caso de efectuar un update.</para>
		<para>Otro uso interesante, sobre todo cuando se trabaja con proyectos ajeno es
			obtener un archivo de "patch" para enviar a los desarrolladores del proyecto
			con acceso de escritura al CVS.  Esto es fundamental en el mundo del Open
			Source para poder filtrar los distintos aportes que se hacen a un proyecto
			desde gente externa a el.</para>
		<para>El comando a usar es "diff", y se puede realizar sobre un archivo o sobre
			el repositorio completo.  Incluso se puede realizar entre nuestro archivo local
			y alguna revision especifica de ese archivo en el repositorio.</para>
		<para>Ejemplos</para>
	<screen><prompt>
cvs diff nuevo.c
cvs diff -r1.1 nuevo.c
cvs diff
	</prompt></screen>
		<para>Lo que hacen estos comandos es mostrar las diferencias de la version de trabajo
			respecto a la version del repositorio del archivo nuevo.c.  El segundo comando
			compara el archivo local respecto a la revision 1.1 de este archivo en el
			repositorio.  Y el ultimo comando busca todas las diferencias entre el directorio
			de trabajo y el modulo en el repositorio.</para>
	</sect1>
	</chapter>
	<chapter>
	<title>Caracteristicas avanzadas de CVS</title>
	<para>Como se dijo en un principio, CVS puede usarse para administrar los cambios
		hechos a un proyecto, pero tambien puede utilizarse para poder cosas mas interesantes
		como por ejemplo realizar distintos	desarrollos en paralelo.</para>
	<sect1>
		<title>Uso de TAG's</title>
		<para>CVS mantiene un registro de los cambios realizados por archivo.  Cada archivo 
			tiene un numero de revision que representa el numero de cambios realizados.</para>
		<para>No existe una forma en que CVS maneje automaticamente algun numero de version
			para el modulo completo en un estado determinado.  Menos aun alguna forma de 
			relacionar esta version con las de otros modulos.</para>
		<para>Por lo tanto, en cuanto a numero de version, CVS veran un conjunto de archivos,
			cada uno con su propio numero de revision sin ningun orden en particular.</para>
		<para>Para poder marcar un estado del respositorio se deben usar TAG's.  Un TAG es un
			nombre que se asigna a todos los archivos del modulo en un instante determinado.
			Este TAG permite obtener versiones del modulo independiente de los numeros de 
			revision de los archivos.</para>
		<para>Usando TAG's se puede marcar por ejemplo el estado del repositorio en el momento
			de hacer un release del modulo.  Los nombres usados por los TAG's son arbitrarios,
			asi que tambien se le puede dar cualquier otro uso que se estime conveniente</para>
		<para>Un ejemplo de marca de TAG sobre el modulo seria:</para>
	<screen><prompt>
cvs tag nombre-de-tag
	</prompt></screen>
		<para>Un TAG realmente es un nombre que se le pone a un numero de revision de un archivo,
			lo que hace el comando es poner el TAG a todos los archivos en su numero de revision
			actual</para>
		<para>Tambien es posible mover un TAG, es decir, aplicar el nombre sobre un conjunto de
			archivos con sus numeros de revision mas recientes.  Ejemplo </para>
	<screen><prompt>
cvs tag -F nombre-de-tag
	</prompt></screen>
		<para>La ventaja de mover un TAG se puede ver a la hora de marcar un release.  Por ejemplo
			si algun cambio se quedo fuera del release, puede aplicarse y luego mover el TAG al
			estado actual.</para>
	</sect1>
	<sect1>
		<title>Uso de ramas (branches)</title>
		<para>Uno de los problemas de trabajar con versiones residentes en CVS, o en cualquier
			otra forma en estado "cambiante", es que no siempre se puede asegurar que el
			modulo se encuentre en un estado usable o estable.  En cierta forma el uso de TAG's
			permite acceder a ciertos estados transitorios, pero cuando se quieren hacer cambios
			profundos que necesitan varios cambios en el repositorio, ya no es tan efectivo.</para>
		<para>Para este tipo de caso existen los branches.  Un branch se puede ver como una linea
			de evolucion de un modulo.  Por defecto se trabaja en un solo branch llamado HEAD.
			En ese branch hay una evolucion del modulo, pero solo existe un antes y un ahora, pero
			no pueden haber desarrollos aislados o paralelos.</para>
		<para>Al usar branches adicionales se puede generar una linea paralela de desarrollo
			del repositorio CVS.  Esta linea paralela se inicia en un estado determinado del 
			repositorio y luego sigue su camino independiente con su propio conjunto de cambios
			y numeros de revisiones.  Se pueden hacer todos los cambios que se deseen en la
			linea paralela, asi como en la linea de desarrollo original, sin que interfieran 
			entre ellos.</para>
		<para>Esta caracteristica puede permitir que un equipo se encuentre trabajando en
			caracteristicas nuevas, mientras que otro equipo trabaja en bug-fixes de una version
			estable.</para>
		<para>Cada rama tiene un nombre definido por el usuario, salvo la rama principal
			que se conoce como HEAD.  Un ejemplo de creacion de una rama es:</para>
	<screen><prompt>
cvs tag -b nombre-de-rama
	</prompt></screen>
		<para>Despues de crear la rama, el directorio local aun seguira en su rama original. 
			Para cambiarse a la rama, se debe usar un update especial.  Ejemplo:</para>
	<screen><prompt>
cvs update -r nombre-de-rama
	</prompt></screen>
		<para>Una vez que se esta en una rama, todos los commit's se haran en esa rama y 
			las otras no podran ver estos cambios.  Se puede cambiar el directorio local
			a cualquier rama que se desee, preservando los cambios hechos a la copia local.</para>
		<sect2>
			<title>Mezcla de ramas (merge)</title>
			<para>Como se ha dicho anteriormente, todas las ramas tienen su entorno propio sin
				afectar al resto.  Pero frecuentemente llega un momento en que los cambios
				realizados en una rama, deben aplicarse sobre otra rama para pasar a formar
				parte de una linea comun de desarrollo.</para>
			<para>A esto se le llama merge o mezcla	de ramas.  Su forma de operar es muy similar
				a realizar un update desde el repositorio.  Es decir, se producen actualizacones,
				mezclas y en algunos casos, conflictos.</para>
			<para>Para mezclar una rama con otra, primero se debe estar en la rama de destino, o
				la rama que consolidara los cambios.  Luego se utiliza un comando para obtener
				los cambios desde otra rama.  Ejemplo:</para>
	<screen><prompt>
cvs update -j nombre-de-rama
	</prompt></screen>
			
		</sect2>
	</sect1>
	</chapter>
	<chapter>
		<title>Practicas recomendadas</title>
		<para>En el uso normal de CVS, el uso basico explicado al inicio de este documento no hay
			mucho que agregar.  El procedimiento es simple y se sigue un ciclo de desarrollo normal
			en comparacion a un desarrollo sin CVS.  Las ventajas se distinguen mas cuando se
			comienzan a usar branches.</para>
		<para>Se puede definir una metodologia para mantener un estado sano de los repositorios CVS,
			de tal forma que siempre se pueda obtener una version estable del CVS, y ademas dar
			flexibilidad para que se puedan estar haciendo cambios en el CVS sin alterar las 
			versiones estables.</para>
		<para>Que se gana con esta separacion de estados del repositorio.  Supongamos que se ha
			trabajado duro en un proyecto y ya se ha hecho un release estable.  La comunidad o
			incluso un cliente podria comenzar el uso de esta version en un entorno real.</para>
		<para>Sin embargo se quiere seguir desarrollando el proyecto, y se necesitan cambios
			profundos al codigo actual, asi como tambien se necesitan hacer bugfixes a la 
			version liberada como estable.  En una forma de trabajo lineal con CVS esto no seria
			posible, ya que los bugfixes se aplicarian sobre la version actual del proyecto, es
			decir, la version en desarrollo.  En este caso no se podria entregar una version
			al exterior que no incluya todos estos cambios profundos.</para>
		<para>Justamente el uso de ramas permite solucionar este problema</para>
		<sect1>
			<title>Uso de ramas estables e inestables</title>
			<para>A lo largo de la vida de un proyecto, se pueden tener distintos releases de
				versiones estables, y releases de versiones inestables o en desarrollo.  Asi
				como bugfixes en el caso de la version estable y construccion en la version
				inestable.</para>
			<para>Una practica comun es usar la rama principal o HEAD como linea de desarrollo.
				En esta rama encontraremos la ultima version del software y estara sujeta a
				todos los cambios requeridos en su contruccion.  Los desarrolladores trabajan
				principalmente sobre esta rama.</para>
			<para>Cada vez que se genere un release inestable. Se puede usar un TAG para marcar
				el estado del repositorio en el momento del release.  De esta forma, se puede
				obtener desde CVS exactamente la version liberada en un momento determinado.</para>
			<para>Al momento de hacer un release estable.  Tambien se puede aplicar un TAG
				para marcar el estado, pero ojo, posteriormente se necesitan hacer bugfixes a
				esta version del repositorio, independiente de lo que haya en desarrollo.  
				Entonces, es el momento de crear un branch estable de CVS.</para>
			<para>Al crear un branch, el repositorio se separara en una linea de bugfixes en
				la rama recien creada y la linea normal de desarrollo en la rama principal.
				De esta forma, siempre es posible obtener una ultima version del release estable
				con todos sus bugfixes utilizando la nueva rama, y en forma separada la ultima 
				version en desarrollo por medio de la rama principal.</para>
		</sect1>
		<sect1>
			<title>Uso de ramas experimentales</title>
			<para>A veces se necesitan hacer cambios profundos al codigo durante periodo
				prolongado de tiempo, esto haria que la version de CVS podria estar totalmente
				rota, independiente de estar trabajando en una rama estable o inestable.</para>
			<para>Este tipo de cambios puede ser parte de un nuevo desarrollo o por ejemplo
				una optimizacion profunda que debe ser muy bien probada antes de ser parte
				del codigo oficial.  En casos como este tambien se puede aplicar una rama.</para>
			<para>Esta rama no tiene ninguna diferencia con las creadas anteriormente, salvo
				el uso que se le va a dar.  Al crear una rama, se pueden hacer todos los cambios
				que sean necesarios sin afectar al resto del equipo que se encontrara trabajando
				en alguna otra rama.  Solamente cuando esten los cambios lo suficientemente
				probados, se podria hacer la mezcla en su rama original.</para>
			<para>Tambien podria darse el caso de que el trabajo no haya dado su fruto esperado,
				y por lo tanto nunca deba formar parte del codigo oficial.  La rama puede
				quedar abandonada sin problemas, y quedara simplemente registrada en la
				historia del proyecto.</para>
		</sect1>
		<sect1>
			<title>Numero de versiones</title>
			<para>Los numeros de versiones usados en los releases no tienen relacion directa 
				con CVS, ya que es algo que pertenece al dominio del proyecto y no al dominio
				de CVS como herramienta.  Sin embargo, se pueden usar algunas convenciones
				para saber siempre con que parte del proyecto estamos trabajando.</para>
			<para>La mayoria de los proyectos Open Source tienen numeros de versiones de tres 
				digitos, organizados en un formato A.B.C.  Para explicar el significado de
				cada digito, se pueden explicar de derecha (C) a izquierda (A) de la 
				siguiente forma:</para>
			<itemizedlist>
				<listitem><para>C : se incrementa cuando se hacen bugfixes y/o cambios pequeños.
					Agrupa varios cambios en un solo cambio lógico a nivel de proyecto</para></listitem>
				<listitem><para>B : cambia cuando se hacen cambios significativos y que 
					significan una real mejora a la versión anterior. Este valor puede ser 
					de dos tipos:</para>
					<itemizedlist>
						<listitem><para>PAR: indica que la version es considerada 
							estable hasta donde se sabe. Se mantiene en su propia rama de 
							release estable</para></listitem>
						<listitem><para>IMPAR: indica que la version no es considerada 
							estable, ya que se encuentra en desarrollo.  Estas versiones estan
							pensadas para liberar ultimos desarrollos que pueden ser utiles al
							resto del equipo, pero que aun no han madurado lo suficiente para 
							llevarlos a producción. Se mantienen en la rama principal</para></listitem>
						</itemizedlist>
				</listitem>
				<listitem><para>A : indica cambios radicales en el software, como son los
					cambios de diseño que lo hacen en cierta forma 
					incompatible con la version anterior</para></listitem>
			</itemizedlist>
			<para>Usando este esquema de numeracion, un proyecto partiria en la rama principal
				con un numero de version 0.1.0.  A medida que se hacen releases de esta version
				de desarollo, la numeracion ira avanzando a 0.1.1, 0.1.2, etc.  En general 0.1.x.</para>
			<para>Llegara un momento en donde es posible hacer un release estable, y tendremos
				una version del repositorio CVS con dos numeros de release, uno estable y otro 
				inestable.  Esto se debe a que el release estable corresponde al mismo codigo de uno
				inestable.  Por ejemplo, si tenemos la version 0.1.8 y esta ya puede ser considerada
				estable, tendremos el release estable 0.2.0 con el mismo codigo de la 0.1.8.</para>
			<para>A partir de ese release se creara una rama para seguir la historia de 0.2.x, y 
				esta rama tendra las versiones 0.2.1, 0.2.2, etc.</para>
			<para>Por otra parte la rama de desarrollo pasara de 0.1.8 a 0.3.0.  Seguira evolucionando
				la rama 0.3.x hasta el proximo release estable 0.4.0.</para>
		</sect1>
	</chapter>
	<chapter>
		<title>Conclusiones</title>
		<para>El rapido avance de los proyectos Open Source no solo se debe al gran entusiasmo
			y esfuerzo de los distintos desarrolladores alrededor de todo el mundo.  Parte
			del logro tamien se debe al uso de herramientas de desarrollo como es el caso de
			CVS entre otras.</para>
		<para>El uso de CVS permite automatizar la compleja tarea de administracion de cambios
			sobre todo el proyecto, incluyendo la evolucion en lineas paralela de un mismo
			proyecto.</para>
		<para>Esta forma de trabajo no solo es aplicable a proyectos Open Source, sino que 
			tambien puede mejorar bastante los procesos de desarrollo de software en
			empresas que generan software cerrado, permitiendoles siempre tener el control
			sobre sus proyectos en desarrollo y la mantencion de releases declarados
			como estables.</para>
	</chapter>
</book>
