Rails developers: Have better context in Git diffs

Git diffs show the surrounding contexts for diff hunks. It does so by applying regular expressions to find the beginning of a context. When it comes to Ruby, however, it will not find method heads and travel up to the class definition:

@@ -24,7 +24,7 @@ class TicketPdf # <=== Actually expected here: the method definition
     ApplicationController.render(
       "tickets/index.html.haml",
       layout: "tickets",
-      assigns: { tickets: tickets }
+      assigns: { tickets: tickets, event_name: event_name }
     )
   end
 end

When Git is told how to recognize a Ruby file, it will correctly display the expected context:

@@ -24,7 +24,7 @@ def tickets_as_html # <=== Now correct
     ApplicationController.render(
       "tickets/index.html.haml",
       layout: "tickets",
-      assigns: { tickets: tickets }
+      assigns: { tickets: tickets, event_name: event_name }
     )
   end
 end

How to configure

# in ~/.gitattributes:

*.rb diff=ruby
*.rake diff=ruby
*_spec.rb diff=rspec
*.feature diff=cucumber

Then tell Git where it can find its global attributes file with git config --global core.attributesfile ~/.gitattributes. (Note that you could configure this on a per-project base as well.)

Ruby support is built in, but RSpec and Cucumber need a little more help:

# in ~/.gitconfig
[diff "rspec"]
  xfuncname = "^[ \t]*((RSpec|describe|context|it|before|after|around|feature|scenario)[ \t].*)$"
[diff "cucumber"]
  xfuncname = "^[ \t]*((Feature|Background|Scenario|Scenario Outline|Examples): .*)$"

Configuring more formats is a simple as extending ~/.gitattributes, and if Git has no built-in support, adding an entry to ~/.gitconfig like above.

Dominik Schöler Over 3 years ago