Estoy tratando de configurar el filtro clean / smudge filter en git para tener un cifrado y descifrado automático de archivos que contienen secretos a través del comando ansible-vault .
La peculiaridad del comando ansible-vault es que no es idempotente (crea un binario diferente cada vez que se invoca en los mismos datos).
Comencé con la implementación sugerida en esta página de blog . Desafortunadamente, no funcionó correctamente, ya que cada vez que se llama mancha (ya sea un pago de git o solo el estado de git), los archivos secretos parecen modificados para git, incluso si no lo es.
Entonces me pregunté si git estaría comparando el binario que tiene en el índice con el archivo actual limpio y filtrado, e intenté construir sobre ese script de la siguiente manera:
#!/bin/sh -x
# clean filter, it is invoked with %f
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
# get the plain text from the binary in the index
tmphead=`mktemp`
git show HEAD:$1 > $tmphead
contenthead=`echo "embedded" | ansible-vault view $tmphead --vault-password-file=$HOME/.vault_password`
export PAGER=cat
echo -n "$contenthead" | tee $tmphead
# if current and index plain text version differ
if [ "`md5sum $tmp | cut -d' ' -f1`" != "`md5sum $tmphead | cut -d' ' -f1`" ]; then
tmpcrypt=`mktemp`
cp $tmp $tmpcrypt
# generate a new crypted blob
echo "embedded" | ansible-vault encrypt $tmpcrypt --vault-password-file=$HOME/.vault_password > /dev/null 2>&1
cat "$tmpcrypt"
else
# just return the HEAD version
cat "$tmphead"
fi
rm $tmp $tmphead $tmpcrypt
La diferencia aquí es que intenta comparar las versiones actual y HEAD de los archivos secretos de texto plano (sin cifrar), y solo en caso de que difieran, generará un nuevo blob binario cifrado con ansible-vault.
Desafortunadamente, después de este cambio, git continúa pensando que el archivo secreto siempre se modifica. Incluso después git add
de volver a crear el archivo, para que se calcule el git blob, git piensa que el archivo es diferente y deja que el cambio vaya al commit. Tenga en cuenta que git diff
devolver cambios vacíos, como debería.
Como referencia, esto es mancha:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
export PAGER='cat'
CONTENT="`echo "embedded" | ansible-vault view "$tmp" --vault-password-file=$HOME/.vault_password 2> /dev/null`"
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
echo "Looks like one file was commited clear text"
echo "Please fix this before continuing !"
exit 1
else
echo -n "$CONTENT"
fi
rm $tmp
y esto es diff:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
export PAGER='cat'
CONTENT=`echo "embedded" | ansible-vault view "$1" --vault-password-file=$HOME/.vault_password 2> /dev/null`
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
cat "$1"
else
echo "$CONTENT"
fi
-n
eco de la mancha, pero eso es una suposición. ¿No hay una opción oculta para git diff que le dice que ignore las terminaciones de una sola línea?