Fri 11 Nov 2022

Better Git diff output for Ruby, Python, Elixir, Go and more

The first line (starting @@) is known as the hunk header, and is there to help orientate the change. It gives us the line numbers for the change (the numbers between the @@..@@), but also a textual description for the enclosing context where the change happened, in this example "class TicketPdf". Git tries to figure out this enclosing context, whether it’s a function, module or class definition. For C-like languages it’s pretty good at this. But for the Ruby example above it’s failed to show us the immediate context, which is actually a method called tickets_as_html. That’s because out of the box Git isn’t able to recognise the Ruby syntax for a method definition, which would be def ticket_as_html.

And it’s not just Ruby where Git struggles to figure out the correct enclosing context. Many other programming languages and file formats also get short-changed when it comes to the hunk header context.

Thankfully, it’s not only possible to configure a custom regex specific to your language to help Git better orient itself, there’s even a pre-defined set of patterns for many languages and formats right there in Git. All we have to do is tell Git which patterns to use for our file extensions.

Some open source projects define their own .gitattributes file. There’s one in Rails. There’s even one in the Git source that enables the diff patterns for Perl and Python.

Configure a global .gitattributes file

Instead of adding a .gitattributes file to every repo we can configure a global .gitattributes file. Just create a .gitattributes file in your home directory, fill it with all the file formats you are interested in and point Git at it.

Related posts

01/05

Fri 11 Nov 2022

Exclude linting & formatting commits when running Git blame

Fri 11 Nov 2022

Why Git blame sucks for understanding WTF code (and what to use instead)

Fri 11 Nov 2022

How focused commits make you a better coder

Fri 11 Nov 2022

List your Git branches by recent activity