Filtros Git clean / smudge para segredos ansible do cofre

Estou tentando configurarfiltro de limpeza / manchas no git ter criptografia e descriptografia automáticas de arquivos que contêm segredosansible-vault comando.

A peculiaridade do comando ansible-vault é que ele não é idempotente (ele cria um binário diferente cada vez que é invocado nos mesmos dados).

Comecei com a implementação sugerida emesta página do blog. Infelizmente, ele não funcionou corretamente, pois sempre que uma mancha é chamada (seja um checkout do git ou apenas um status do git), os arquivos secretos parecem modificados para o git, mesmo que não o sejam.

Então, me perguntei se o git compararia o binário que ele possui no índice com o arquivo atual filtrado e limpo, e tentei criar esses scripts da seguinte maneira:

#!/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

A diferença aqui é que ele tenta comparar as versões atual e HEAD dos arquivos secretos de texto sem formatação (não criptografados), e somente no caso de divergir eles produzem um novo blob binário criptografado com o ansible-vault.

Infelizmente, após essa mudança, o git continua pensando que o arquivo secreto é sempre modificado. Mesmo depoisgit addAo gravar o arquivo novamente, para que o git blob seja computado, o git acha que o arquivo é diferente e deixa a alteração entrar no commit. Observe quegit diff retornar alterações vazias, como deveria.

Para referência, isso é 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

e isso é 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

questionAnswers(0)

yourAnswerToTheQuestion