sábado, 23 de julio de 2011

Publicar el repo y el historial, pero sin contraseñas harcodeadas

El historial, la secuencia de commits detallando todo lo que fue cada "snapshot" es muy util, pero ¿Que pasaria si quisiesemos publicar branches en cuyo historial hay contraseñas que no queremos que el publico las vea ?

Para todo "gitero" el historial es importante, pero tambien lo es evitar la fuga de informacion y mas cuando somos concientes de que si hacemos ese "push", esa contraseña o codigo de acceso sera publico

La respuesta a esto es el comando filter-branch ¿ Que hace filter-branch ? crea un commit inicial aparte (que es como el commit inicial del repositorio, no tiene parent) y va copiando los commits del branch que donde estemos parados al momento de ejecutar el comando, pero esto lo hace aplicandole un filtro que se define como argumento del comando

filter-branch tiene muchas opciones muy interesantes, pero la que mas sirve para el caso que describo en este post, es la opcion --tree-filter, que ejecuta una secuencia de comandos a cada tree de cada commit, esa secuencia podria agregar, eliminar, mover o crear archivos. Asi, el siguiente comando eliminaria un archivo Web.config de todo el historial haciendo que no se pueda recuperar ninguna version de el de ningun commit en el historial:

git filter-branch --tree-filter 'rm Web.config'


NOTA: no olvidar poner la ruta completa si corresponde, el script se ejecutara en el root directory del proyecto

A algunos puristas podria no gustarle esa opcion, ya que eliminar ese archivo vital dejaria invalido y "unbuildeable" esos commits pasados. En lugar de eso se podria usar algo mas especifico y recurrir al amigo "sed" para editar ese archivo y remover la contraseña

git filter-branch --tree-filter "sed 's/mipasswordloco/insert your password here/g' Web.config > Web.config.bkp; mv Web.config.bkp Web.config"

En este caso, en lugar de simplemente eliminar el archivo, se lo esta procesando con sed, una "navaja suiza" de la shell para editar archivos de texto desde la linea de comandos de manera no interactiva.

Hay dos comandos en el script separados por punto y coma, el primero es sed que reemplaza el texto "mipasswordloco" por "insert your password here" y usa el parametro g para indicar que debe reemplazar todas las ocurrencias en cada linea del archivo de texto (ver la man page de sed para mas informacion), el segundo parametro escribe en Web.config los cambios realizados con un move, recalco que esto es asi porque no se debe dejar ningun archivo extra o formara parte del tree tambien (que no es lo que se esta tratando de hacer en este caso)

Aplicando scripts mas complejos como este, despues de ejecutar filter-branch es conveniente revisar el historial para verificar que efectivamente se obtuvo el resultado buscado

Si por casualidad hicieron un git-filter-branch y despues se arrepintieron, se restaura el branch con la penultima entrada del reflog, asi:

git reset --hard HEAD@{1}


Links

No hay comentarios:

Publicar un comentario