Tools like git-crypt or Rails credentials provide an encryption layer for managing sensitive files within Git repositories. However, when using Emacs vc-diff on repositories protected by these tools, the diff output is incorrect because vc-diff
compares the encrypted binary files directly rather than comparing the decrypted files. This occurs even when the repository is unlocked and the decrypted content is available, resulting in a failure to display meaningful diffs.
The root cause
Internally, vc-diff
uses Git commands to compute diffs. However, it does not invoke them with the --textconv
flag by default. Without --textconv
, Git does not apply content filters, including decryption filters specified by tools such as git-crypt
or Rails credentials. Consequently, Emacs vc-diff
displays diffs of the raw binary files rather than the decrypted content.
The solution
A workaround for enabling human-readable diffs of encrypted files in Emacs is to modify the vc-git-diff-switches
variable to include the --textconv
argument:
;; Emacs vc-diff fails to produce meaningful output on git-crypt enabled
;; repositories because it does not use Git's --textconv flag by default. This
;; flag enables Git to apply text conversion filters (e.g., for encrypted files)
;; when generating diffs. Without it, vc-diff compares raw encrypted blobs, even
;; when the working tree shows decrypted content.
(unless (member "--textconv" vc-git-diff-switches)
(setq vc-git-diff-switches (cons "--textconv" vc-git-diff-switches)))
Code language: Lisp (lisp)
Adding the --textconv
flag to the vc-git-diff-switches
variable enables Emacs vc-diff
to apply the text conversion filters specified in .gitattributes
. This resolves the issue by displaying the diff of the decrypted files instead of the encrypted binary files.