Control de Versiones - Guión

8

Click here to load reader

Transcript of Control de Versiones - Guión

Page 1: Control de Versiones - Guión

Guión charla control de versiones

Que controla un VCSUn VCS controla las diferencias (deltas) entre versiones de un mismo fichero. Una versión es una foto del contenido de un fichero. Ejemplo de cálculo de diferencias en una imagen:

Revisión 1 Revisión 2 delta

GIF: 62046 bytes GIF: 62591 bytes GIF: 8280 bytes

(también nos sirve para ganar muy rápido al “busca las 10 diferencias”)

A esta técnica se le llama delta-compression.

La idea de fondo es que si somos capaces de aplicar delta a la primera revisión, obtendremos la segunda revisión.

Esto con ficheros de texto es trivial y en entornos Unix lo llevamos haciendo desde los 70 con los comandos diff y patch. Del concepto de patch (parche) se evolucionó hacia el concepto de Control de Revisión y de aquellas barros, estos lodos.

Anécdota: hasta hace bien poco, la horda de “contributors” del kernel de linux mandaba parches al mismísimo Linus Trovalds, quien los iba aplicando a mano en su copia local. Estuvieron así durante años hasta que les dio por dominar el mundo con Git.

Page 2: Control de Versiones - Guión

¿VCS = backup?¡NO!

Bueno, vale, es algo que se parece mucho a un backup, pero va mucho más allá. E incluso, usarlo como backup es motivo suficiente para usar un VCS en cualquier proyecto.

El control de versiones, en definitiva, va de poder responder a estas preguntas:

1. ¿Qué constituye una versión concreta de mi trabajo? ¿Cómo puedo reproducir un determinado estado de cualquiera de las versiones que he entregado?2. ¿Quién ha hecho qué, cuándo y por qué? No solo es útil para saber cuándo han ido mal las cosas, sino también para contar la historia de tu producto.

(Traducido de Continuous Delivery, de Jef Humble y David Farley)

Además, resulta que tiene unos mecanismos excepcionales para permitir la colaboración entre distintos “actores” en el marco de un proyecto.

Podemos editar el mismo fichero a la vez y nuestro VCS favorito se desvivirá por intentar mezclar todos los cambios sin romper nada. Muchas veces lo consigue y otras, nos toca arreglar “los líos de otros” (nunca los nuestros, eh?, que siempre hacemos los commits bien).

Branching y merging: el comienzo del finNormalmente trabajaremos en la rama troncal o maestra de nuestro repositorio de CVS. Cuando queremos desviar la evolución de nuestro desarrollo por un camino distinto, hacemos un branch, o rama en inglés. A partir de ese momento, los deltas que el CVS almacene para los ficheros de la rama irán por separado de los deltas de la rama principal.

Cuando queremos que los deltas acumulados aisladamente dentro de una rama se importen a la rama principal, hacemos un merge

A priori son funcionalidades que tienen muy buena pinta. Aislar una determinada vía de desarrollo para una sola nueva funcionalidad y no ensuciar la rama principal... ¿Ensuciar? Si para desarrollar algo nuevo vamos a ensuciar la rama principal, seguramente que estamos haciendo algo mal.

Page 3: Control de Versiones - Guión

En última instancia, según los autores de Continuous Delivery (que de esto saben un huevo), todo commit al CVS debe constituir una pieza de producto entregable. Muchos de los branchs que creamos para no mancillar la castidad de la rama principal, suelen terminar conteniendo mucho código duplicado y cuanto más largo es su recorrido, más difícil suele resultar la reincorporación del branch a la rama principal.

Por otro lado, si el branch no va a ser reincorporado al branch principal y no va a estar activo indefinidamente, puede tener sentido prepararlo.

En cualquier caso, esta es solo mi opinión y os recomiendo experimentar y sacar vuestras propias conclusiones.

Marcha atrás: la esquiva quimeraEn el caso de que una entrega no llegue a buen puerto, el control de versiones nos puede ayudar a recuperar un estado previo de nuestro proyecto.

Sin embargo, en un proyecto de cierta envergadura, resulta complicado llevar una gestión tan exigente sobre el control de versiones como para permitir el rollback a la versión anterior.

Aunque es posible hacerlo, muchas veces tendremos que valorar su coste frente a otras alternativas menos elegantes como el nunca suficientemente valorado backup previo o mediante el despliegue de una nueva versión del proyecto que

corrija cualquier defecto detectado en la entrega. A veces la huida hacia delante es la mejor opción.

Subversion para geeksMergeo parcial entre dos branches:

1) Nos movemos al punto en el que queremos mergear y obtenemos la ruta actual sobre la que queremos mergear:

cerebro:/src/bar/chuchu/blabla cocotero$ svn infoRuta: .URL: http://foo.com/bar/trunk/chuchu/blablaRaíz del repositorio: http://foo.comUUID del repositorio: 4fda1d5b-c8f9-44cf-8ad8-48e2fb4af63b...

(tomamos nota de la URL)

2) Ejecutamos un merge contra la misma ruta del branch rc4:

cerebro:/src/bar/chuchu/blabla cocotero$ svn merge http://foo.com/bar/trunk/chuchu/blabla http://foo.com/bar/branches/rc4/chuchu/blabla .

Page 4: Control de Versiones - Guión

3) Revisamos los cambios y hacemos commit de lo que haga falta.

Añadir y eliminar externals

cerebro:/src/bar/blabla cocotero$ svn propset svn:externals “chuchu http://foo.com/bar/trunk/chuchu” vendor/.

Crea un external en vendor/chuchu que apunta al repo que indicamos

cerebro:/src/bar/blabla cocotero$ svn propdel svn:externals vendor/.

Elimina cualquier external que pueda haber en vendor. Si necesitas borrar un external en concreto, puedes usar el comando svn propedit svn:externals

Ignorar ficheros o directorios

cerebro:/src/bar/blabla cocotero$ echo “*” > .svnignorecerebro:/src/bar/blabla cocotero$ svn add .svnignorecerebro:/src/bar/blabla cocotero$ svn propset svn:ignore -F .svnignore .

Ignoramos cualquier cosa dentro de blabla que no esté ya en nuestro repo

cerebro:/src/bar/blabla cocotero$ echo “cache” > .svnignorecerebro:/src/bar/blabla cocotero$ svn add .svnignorecerebro:/src/bar/blabla cocotero$ svn propset svn:ignore -F .svnignore .

Ignoramos el fichero o directorio cache dentro de blabla

Git para humanosAntes de empezar, diré que la clave es usar GitHub. Si usas GitHub unas semanas le coges el tranquillo a Git sin problemas.

Rompiendo el modo centralizado

1) Crea un repo que sera el “maestro”2) Te haces un fork del maestro para ti

cerebro:/src/ cocotero$ git clone [email protected]:ggalmazor/BusinessLayer.git

3) Te añades al resto de contributors como origen

cerebro:/src/ cocotero$ git remote add ruben [email protected]:regiluze/BusinessLayer.git cerebro:/src/ cocotero$ git remote add mikel [email protected]:mintxaus/BusinessLayer.git

Page 5: Control de Versiones - Guión

4) Te traes sus repos:

cerebro:/src/ cocotero$ git fetch rubencerebro:/src/ cocotero$ git fetch mikel

5) Premio:

cerebro:/src/ cocotero$ git branch -a* master remotes/mikel/master remotes/origin/HEAD -> origin/master remotes/origin/master remotes/ruben/master

Tienes todos sus branches en local :) Ahora puedes mergearte con ellos sin pasar por el repo “maestro”.

Además de esto, podrás organizar mejor las aportaciones del equipo mediante pull-requests.

Supervivencia 101: manual de etiquetaHaz commits a menudo

El diámetro de la potencial cagada es proporcional al tamaño del commit. Tus compañeros te lo agradecerán.

Trata de que 1 commit = 1 funcionalidad/historia de usuario/bug/ticket

Añade mensajes descriptivos

¡Hazlo siempre! No hay excusa.

Que la primera línea contenga un resumen del commit.

Que el resto de líneas sean el detalle.

Si usas Subversion y Trac añade un link al ticket que resuelves y para que en el Trac salga un enlace al commit.

Si usas GitHub aprovecha para meter MarkDown y enlaza al issue relacionado con el commit.

Si usas historias de usuario mete una referencia al código de la historia que resuelves.

Piensa en otras maneras de mejorar los mensajes de commit y ponlas en práctica.

Ten en cuenta que, con toda probabilidad, tus compañeros son unos psicópatas y que saben dónde vives o, peor aún, los bares que frecuentas.

Page 6: Control de Versiones - Guión

Rescepto a los commits ajenos

No pises los commits de los demás.

Evita hacer commits de ficheros que solo consistan en cambios de indentación o líneas vacías. A no ser que pongan las llaves en la línea siguiente. Si es así, tenéis mi permiso para arrasar.

Evita cambios en ficheros debidos a distintos encodings.

VCS != basurero

Usa la definición de ficheros y directorios ignorados de tu VCS.

No hagas commit de las carpetas que genera tu IDE para el proyecto.

No hagas commit de las carpetas de la papelera de reciclaje o los _DS_STORE

Convén con tus compañeros la estructura de directorios del proyecto y respétala

Blame before you claim

Ante cualquier posible afrenta, usa el comando blame (o similar) de tu VCS para ver quién ha sido el malhechor y cuales eran sus verdaderas intenciones. En el mejor de los casos, estaban corrigiendo una cagada tuya. En el peor, tendrás pruebas irrefutables.

Resolución de conflictos

Si las opciones de tu VCS no son suficientes o no se te da bien el comando de línea, usa alguna herramienta gráfica como Meld para aplicar los cambios a mano. Eclipse incluye un editor de conflictos bastante majo y SmartSVN también. ¿Git tiene alguna?

Por último: usa el comando de línea

Adquirir expertise con la shell es algo que revierte en muchas ventajas, no solo para manejar un VCS. Los clientes gráficos suelen ser pesados y solo pueden aportar alguna ventaja en operaciones complejas de verdad. El comando de línea, al contrario, es todo lo rápido que puede llegar a ser y los interfaces de usuario suelen estar muy bien pensadas para sortear el handicap del “modo texto”.

Además, podrás fardar ante propios y ajenos con tu shell kungfu.

Page 7: Control de Versiones - Guión

Centralizado y distribuidoDistribuido es cuando los participantes hacen checkin y checkout entre ellos. ¿El ejemplo más conocido? Git

Centralizado es cuando los participantes hacen checkin y checkout de un repositorio central. ¿El ejemplo más conocido? Git

¿Cuál es la diferencia? Los del centralizado no tienen más remedio.

Muchos estaréis usando Git como si de un VCS centralizado se tratara. ¿Usáis remotes distintos que origin?

En el fondo, no importa demasiado si es centralizado o remoto. Mi percepción después de 6 años gestionando servidores Subversion y 1 con Git es que montar un Subversion está chupado y que montar un Git no compensa existiendo servicios como GitHub.

Si alguien necesita instrucciones o ayuda para montar cualquiera de estos dos VCS le puedo echar una mano o, al menos, ponerle en el buen camino.

Page 8: Control de Versiones - Guión

Caso de uso: desarrollamos un Wordpress para un clienteSituación

Tenemos un que desarrollar y mantener un site con Wordpress. Además, tenemos que añadir una serie de plugins y un tema que hemos desarrollado nosotros mismos.

Planteamiento

Creamos un repo para cada plugin de nuestra cosecha y para el tema que vamos a implantar.

Creamos un repo para el Wordpress que vamos a entregar

Repo: Plugin

Contiene un único directorio tal y como se llamará cuando lo pongamos en la carpeta /wp-content/plugins del Wordpress. Por ejemplo “cocotero_delux”. La estructura de directorios básica va a contener los siguientes elementos:

cocotero_delux/ _sql/ README.md En el fichero Readme.md guadaremos un registro de los cambios que le vamos haciendo a las distintas releases y en el directorio sql deberíamos guardar un fichero schema.sql en el que iríamos almacenando la estructura de datos completa de nuestro plugin. También podríamos almacenar un fixtures.sql en el caso de que quisiéramos que nuestro plugin tuviera algo de información de partida en dicha estructura y por cada release que nos cambiara la estructura tendríamos un par de ficheros con alters para realizar el upgrade y el downgrade sobre la base de datos de producción.

Repo: Theme

Al igual que con los plugins, contiene un único directorio donde ponemos los ficheros y directorios de nuestro tema

Repo: Blog de nuestro cliente

Lo creamos y copiamos los ficheros de Wordpress en él. Hacemos commit y añadimos nuestros plugins y nuestro tema como submódulos de Git con el comando git-remote.

En este caso no vamos a tener un directorio para los sql ya que es Wordpress quien se encarga de los upgrades de base de datos.

De cara a las puestas en producción o las actualizaciones automágicas de Wordpress, automatizaremos mediante un script la generación de un backup completo (¿idea para un plugin?)