Empezando por el final, las instrucciones a realizar son:
$ svn log -v -r 400:`svn info | grep Revisión | awk '{print $1}'` | grep dirprj | awk '{print $1}' | sort | uniq | awk '{print "."$0}' > dirprj-`svn info | grep Revisión | awk '{print $1}'`.txt
y luego....
$ tar -zcvf dirprj-`svn info | grep Revisión | awk '{print $1}'`.tar.gz -T -`svn info | grep Revisión | awk '{print $1}'`.txt
Traducido al verbo humano, el proceso es como sigue:
Así, a palo seco, la instrucción de consola es un poco bestia. Voy desglosando instrucciones para sacar conclusiones:
svn log es una llamada que se realiza sobre subversion para saber la actividad que ha tenido el repositorio. Al aplicar la opción -v, lo que conseguimos es que nos muestre los archivos alterados para cada actualización.
Si sacáramos todo el log quizá nos pasamos 10 minutos viendo pasar listas de archivos modificados, con lo que lo mejor es establecer un margen de revisiones. Para especificar un número de revisiones se utiliza la opción -r, que tiene la forma:
-r a:b, donde a es la revisión más antigua y b la más actual. En nuestro caso, nos interesa que b sea la última revisión realizada. Para no tener que estar cambiando continuamente el valor, ejecutamos la instrucción:
svn info | grep Revisión | awk '{print $1}'
Para ir más rápido, utilizo directamente las salidas `entrecomillando las instrucciones`. Eso sustituye el la instrucción entrecomillada por el valor devuelto.
La instrucción grep que se muestra a continuación es una cuestión de estilo. El caso sirve para los repositorios que almacenan más de un proyecto, como es mi caso. Eso permite que los subdirectorios identifiquen los proyectos relacionados. Este punto es el más adaptable a cada caso, como expone el propio manual de subversion en cuanto a estilos de gestión de repositorios se refiere. Para el caso, la instrucción:
grep nos devuelve sólo los archivos que tienen en su path el nombre indicado. La desambigüación no está de más para estos casos.
Los listados de log del subversion están bastante, maquetados, por decirlo de algún modo. Al menos la versión por defecto encuadra los resultados con guiones u otros caracteres. Además, para cada archivo indica qué tipo de modificación se ha realizado. Eso aclara la visualización pero entorpece el proceso de cañerías.
Para eliminar ese ruido, ejecuto awk:
$ ... | awk '{print $1}' | ...
Esto hace que de todos los resultados retornados por grep, me coja "la segunda palabra", es decir, la secuencia de caracteres posterior al primer conjunto de espacios. Esto lo que devuelve en definitiva es la ruta del archivo.
Dado que es probable que hayan habido varias alteraciones de un mismo archivo, decido ordenar los resultados (sort) y luego eliminar de la lista ordenada los valores repetidos. Cambiar el orden de estas dos instrucciones no da buenos resultados, porque uniq sólo mira si la fila actual es igual que la anterior.
Dado que el repositorio no tendrá un path completo, la última instrucción le añade un punto (.) al principio de toda la cadena, para dar a entender que se refiere a un path relativo al path actual (en awk, el valor de $0 equivale a toda la cadena).
¿Por qué?
Pues porque svn me devuelve "paths absolutos" respecto la raíz del repositorio, pero cuando trabajo directamente sobre la raíz de mi sistema operativo, esas rutas no son correctas. Es importante tener claro en cada momento el contexto de ejecución, y especialmente cuando trabajamos con pipes.
Almacenamos la lista de rutas limpitas y preparadas para la exportación en un archivo de texto, que para el caso hemos denominado combinando el nombre del directorio del proyecto y el número de revisión, así no hay que estar pendientes de grandes fiascos...
Para acabar, llamaremos al programa tar, utilizando la opción -T, que nos permite seleccionar de un archivo la lista de recursos a empaquetar. Así pues, ejecutamos la instrucción comentada antes:
$ tar -zcvf dirprj-`svn info | grep Revisión | awk '{print $1}'`.tar.gz -T -`svn info | grep Revisión | awk '{print $1}'`.txt
Como antes, el entrecomillado de svn info nos devuelve un valor. Por eso, es importante entender que lo que acaba recibiendo el ordenador (suponiendo que dirprj=proyecto1 y que la última revisión sea 425) es algo así como:
$ tar -zcvf proyecto1-425.tar.gz -T proyecto1-425.txt
Por lo menos detecto las siguientes mejoras posibles:
Si quieres saber más...
Puedes seguir investigando sobre los anteriores comandos en los enlaces comentados anteriormente. Te recomiendo awk (puedes empezar por algunos ejemplos de awk), ese gran olvidado que yo conocí a fondo estudiando procesamiento del lenguaje natural, cuando para procesar un corpus y categorizar los términos utilizamos esta herramienta. Ahora ya forma parte de mi vida laboral :-D.
© 2007 and beyond Mario Alberich, licensed under CC-BY-SA unless stated otherwise.