By default, the git diff
algorithm compares changes in Elisp files line by line without understanding the structural semantics of Emacs Lisp files. This means that when modifications are made within functions, the diff output does not convey how those changes relate to higher-level code constructs such as functions or macros.
As a result, reviewers are presented with fragmented and often verbose diffs where the context of a change, such as which function it belongs to, is not always readily apparent. This lack of structural awareness can make it difficult to assess the purpose and impact of changes efficiently.
Git can be configured to recognize function or macro definitions explicitly, ensuring that diffs are presented at the function or macro level rather than as arbitrary line changes. Here are the steps:
Step 1 – The Git configuration for Emacs Lisp diffs
Add the following elisp Git driver to your ~/.gitconfig
file:
[diff "elisp"]
xfuncname = ^\\([^[:space:]]*def[^[:space:]]+[[:space:]]+([^()[:space:]]+)
Code language: plaintext (plaintext)
The regular expression above matches lines that begin with typical Emacs Lisp definition forms, such as defun, defmacro, and other def* constructs. It detects the symbol being defined, allowing Git to handle changes at the function or definition level intelligently. This configuration can also be found in the autogen.sh file, which is part of the Emacs source code.
Step 2 – Associating the diff driver with *.el files
Once the custom diff driver is defined, it needs to be associated with Elisp files. This is accomplished by adding the following line to the ~/.gitattributes
file:
*.el diff=elisp
Code language: plaintext (plaintext)
With this setup, Git will apply the elisp
diff driver to all files with the .el extension, using the custom pattern to identify function boundaries.
Conclusion
This configuration generates diffs that focus on changes within the scope of individual function and macro definitions, rather than arbitrary lines. As a result, reviews of Emacs Lisp code become more precise and contextually relevant. Reviewers can easily identify which functions were modified, without being distracted by unrelated or excessive diffs.
Related links
- The configuration in this article is part of the author’s
~/.gitconfig
file is available in the jc-dotfiles repository. - Enhancing Git configuration ~/.gitconfig for performance, efficiency, data integrity, and workflow automation
- git-diff documentation