gitansiblegit-configansible-vault

Hide diff for `git add --patch` for ansible-vault encrypted files


Usually I use git add --patch to stage chunks of diffs interactively.

In my ansible repository I use ansible-vault to encrypt variable files. When a encrypted file was changed, git can't show a meaningful diff for chunks of course, because the entire encrypted file changes when a single line of the plaintext content changes. This is why I want git add --patch to handle these changes as binary files (even if they only contain ASCII characters). Usually this can be done by adding this to the .gitattributes:

**/vault.yml binary

However, I want to be able to use git diff and show the plaintext diff. That's why my .gitattributes looks like this:

**/vault.yml diff=ansible-vault merge=binary

And in the config of git I've set diff.ansible-vault.textconv to "ansible-vault view".

My question: Can I configure git diff to use ansible-vault view to show the diff of vault encrypted files but otherwise tell git to handle this file as binary? Especially for git add --patch?


Solution

  • It looks like I can achieve what you wanted. All your configurations are correct, but one more step is needed—you need to instruct Ansible on how to automatically decrypt your vault.yml file. To do this, you need to specify vault-id when encrypting your vault.yml file, and update ansible.cfg to include this ID and its passphrase. I use the vault_identity_list configuration for this.

    The header of vault.yml should looks like this:

    $ANSIBLE_VAULT;1.1;AES256;dev
    

    Here, dev is a vault-id

    And ansible.cfg should looks like this:

    [defaults]
    vault_identity_list = dev@~/.ansible/dev_vault
    

    Here, ~/.ansible/dev_vault is the path to the file containing your Ansible password.

    Testing:

    $ cat .gitattributes
    mks/vars/secrets/test.yml diff=ansible-vault merge=binary
    $ git diff              
    diff --git a/mks/vars/secrets/test.yml b/mks/vars/secrets/test.yml
    index f1f2e43..b6020c4 100644
    --- a/mks/vars/secrets/test.yml
    +++ b/mks/vars/secrets/test.yml
    @@ -1 +1 @@
    -TEST: SECRET
    +TEST: SECRET1
    $ rm .gitattributes
    $  
    $ git diff          
    diff --git a/mks/vars/secrets/test.yml b/mks/vars/secrets/test.yml
    index f1f2e43..b6020c4 100644
    --- a/mks/vars/secrets/test.yml
    +++ b/mks/vars/secrets/test.yml
    @@ -1,6 +1,6 @@
    -$ANSIBLE_VAULT;1.1;AES256;dev
    -62616662613966343561393538623262613937333862383763313436646135363963343733393130
    -3162626166373735306630393861386230343966393561350a343734353930343830363061633562
    -63383035343639616436313335313137303063653533303564623761646366613437393763663437
    -3038616638363465330a393562666536303964633037646235646132633964643630636565346232
    -3938
    +$ANSIBLE_VAULT;1.2;AES256;dev
    +63376434353533626138656339616563366134666266373838323033643266333464336435663637
    +6666633665373165396661356265393834313937643562310a363064656461383133633263343663
    +66666563643331333564313032396262356165333432636435323965373061386462306537383136
    +3131343361353139310a343435623838376538376637323064613861393032626166366433626335
    +3035
    

    Update (I left the previous answer for reference, maybe it will be useful to someone.)

    If you want to use textconv to convert ansible-vault encrypted files to the representation for human viewing, but otherwise treat them as binary files, you can use the diff.*.binary configuration option:

    [diff "ansible-vault"]
        textconv = ansible-vault view
        binary = true
    

    Here's an example with some testing:

    $ cat .gitattributes 
    **/test.yml diff=ansible-vault
    
    $ git diff
    diff --git a/mks/vars/secrets/test.yml b/mks/vars/secrets/test.yml
    index 175555f..c0262aa 100644
    --- a/mks/vars/secrets/test.yml
    +++ b/mks/vars/secrets/test.yml
    @@ -1 +1 @@
    -TEST: SECRET
    +TEST: SECRET1
    
    $ git add --patch mks/vars/secrets/test.yml 
    Only binary files changed.
    

    You can find more information about marking files as binary here