Create Git diffs with proper function context
TL; DR
For years I have been annoyed (slightly, but still) that Git diffs for PHP classes always just contained the class header instead of the method header as the function context. I finally got round to doing a bit of research and it turns out that the solution is astonishingly easy: just one small and simple config file and it will magically work.
The problem
You might have noticed it, and maybe been annoyed by it, too: when you create a diff file with Git and have changes inside PHP class files, you get hunks that look like the following:
@@ -40,6 +40,7 @@ class SearchApiViewsHandlerFilter extends views_handler_filter {<br> '<=' => t('Is less than or equal to'),<br> '=' => t('Is equal to'),<br> '<>' => t('Is not equal to'),<br>+ '!=' => t('Is REALLY not equal to'),<br> '>=' => t('Is greater than or equal to'),<br> '>' => t('Is greater than'),<br> 'empty' => t('Is empty'),
So, where you would normally expect the function context, to quickly get an idea what that change means, the diff instead just contains the class name, which is much less helpful (especially if the file name already tells you the class).
Well, after years of being regularly (slightly) annoyed by this (more so in recent years, with the OOP shift in Drupal 8), I finally searched this new place called "the interwebs" and arrived at the very simple solution.
The solution
It turns out Git's diff functionality already has support for creating the right function context information for various file types – it just doesn't know which files correspond to which file type. (It seems not even the standard .php
extension is recognized by default.)
To remedy this, simply create a file with the following contents:
*.engine diff=php<br>*.inc diff=php<br>*.install diff=php<br>*.module diff=php<br>*.php diff=php<br>*.profile diff=php<br>*.test diff=php<br>*.theme diff=php
Save the file either in .git/info/attributes
or .gitattributes
(for just the local project), or (to change this globally) in $HOME/.config/git/attributes
(or $XDG_CONFIG_HOME/git/attributes
, if that variable is set). That's it – testing again, we now see the proper function context in the diff:
@@ -40,6 +40,7 @@ public function operator_options() {<br> '<=' => t('Is less than or equal to'),<br> '=' => t('Is equal to'),<br> '<>' => t('Is not equal to'),<br>+ '!=' => t('Is REALLY not equal to'),<br> '>=' => t('Is greater than or equal to'),<br> '>' => t('Is greater than'),<br> 'empty' => t('Is empty'),
Much better, right?
Note: I haven't yet found out where to put the global attributes file for Windows. If you know, please post a comment and tell me, and I'll include it here.
Background information
For more information on Git attributes, please see the documentation. I didn't know about this at all before, but it seems there's actually a lot you can configure per file type, so there might be other very practical tips for customization.
If you find or know of any, please post them so others can profit from them, too – just as I hope this post was useful to at least a few of you!
As an afterthought, I've also added this tip to the Git documentation in Drupal.org's handbook. Hopefully, more people will find it that way.