Estimated reading time: 2 minutes

Context aware diffs with git

Earlier this week Luke Cox asked in response to a patch I sent:

What version of git are you using? Mine doesn’t seem to produce the right location output for format-patch.

git, by default, displays a function name in the hunk header of its diff output. It produces some really nice output for certain languages, but out of the box it doesn’t display nice information for all the file formats you may use.

diff --git 1/config/dconf/user.ini 2/config/dconf/user.ini
index d4bf8a0..5559f9f 100644
--- 1/config/dconf/user.ini
+++ 2/config/dconf/user.ini
@@ -5,5 +5,5 @@ org/gtk/settings/file-chooser
 sort-column='name'
 show-size-column=true
 startup-mode='cwd'
-show-hidden=false
+show-hidden=true
 sort-directories-first=true

The patch I sent Luke included a significant change to an .ini format file, including some mostly accurate location information in the hunk header as in the example above. It wasn’t because I use a newer version of git, just that I’ve set it up to use different matchers for different files. In my ~/.config/git/config I have the following snippet to use better function names in ini and adr files:

[diff "ini"]
    funcname = "^\\[\\(.*\\)\\]$"
[diff "adr"]
    funcname = "^#.*$"

Warning

Be sure to escape backslashes, as the config parser will eat a single backslash before it is even seen by the diff driver. For the full details on the format, see gitattributes(7).

And, to enable them you must tell git which files to use the new matchers with by editing the .gitattributes file:

*.ini diff=ini
*.adr diff=adr

The funcname values are simple RegEx to search for, so in the ini example it is searching for a line that begins with a [ and ends with a ] as these are the common section headers. And the adr matcher just specifies a line that begins with a #.

It is important to match the entire string or to use grouping, as it is the matched content that is used in the diff hunk’s output. As can be seen in the ini example, I group only the text between [ and ] so that the brackets aren’t included in the header.


Authenticate this page by pasting this signature into Keybase.

Have a suggestion or see a typo? Edit this page