16

(git version 1.6.5.7)

When I run git diff the output has a nice scope hint after the line numbers for my Python scripts, e.g.:

diff --git a/file.py b/file.py
index 024f5bb..c3b5c56 100644
--- a/file.py
+++ b/file.py
@@ -14,6 +14,8 @@ TITF: Test Infrastructure Tags Format
...
@@ -1507,13 +1533,16 @@ class Tags( object ):
...

Note that the line numbers are followed by TITF: Test Infrastructure Tags Format and class Tags( object ):. The first patch applies to module scope and the description TITF: Test Infrastructure Tags Format is the module's description. The second patch applies to a method of the Tags class.

  1. How does git generate these descriptions?
  2. How can I tweak them to show the method name that the patch applies to?

2 Answers 2

16

Git uses a regular expression to find a suitable line for the hunk headers. Python's is built-in, but you should be able to define your own expression in your ~/.gitconfig:

[diff "python"]
        xfuncname = "<regex goes here>"

More about this here.

Edit: The built-in python regex seems to be defined in userdiff.c (line 53), although my regex-fu is not good enough to actually understand exactly what it does...

PATTERNS("python", "^[ \t]*((class|def)[ \t].*)$",
         /* -- */
         "[a-zA-Z_][a-zA-Z0-9_]*"
         "|[-+0-9.e]+[jJlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
         "|[-+*/<>%&^|=!]=|//=?|<<=?|>>=?|\\*\\*=?"
         "|[^[:space:]|[\x80-\xff]+"),
         /* -- */
5
  • Interestingly ".py diff=python" changes the behavior to be as I'd like even without defining a custom [diff "python"], but ".py +diff" (apparently my default) behaves as shown in my question.
    – RobM
    Commented May 6, 2010 at 18:03
  • 1
    ".py diff=python" tells git to use the options defined under [diff "python"] (or the predefined default), ".py +diff" just enables a textual diff. This switch is usually used for disabling diffs for files that are not always detected as binary, e.g. "*.ps -diff" will treat PostScript files as binary and thus doesn't show a diff.
    – DataWraith
    Commented May 6, 2010 at 18:12
  • although for binary files it may be advisable to set "*.ps binary" which is an alias for "-crlf -diff", i.e. it disables CRLF<->LF processing for the file too.
    – araqnid
    Commented May 6, 2010 at 22:53
  • 2
    The GNU diff has similar -p / --show-c-function option, which was inspiration for its git-diff equivalent / generalization. Commented May 7, 2010 at 1:07
  • 2
    For those who wonder what "*.py diff=python" is, I'd like to mention that this is a line in a .gitattributes file (if I'm not mistaken). Commented May 7, 2010 at 12:34
1

With Git 2.25 (Q1 2020), the userdiff machinery has been taught that "async def" is another way to begin a "function" in Python.

See commit 077a1fd (19 Nov 2019) by Josh Holland (anowlcalledjosh).
(Merged by Junio C Hamano -- gitster -- in commit 9502b61, 05 Dec 2019)

userdiff: support Python async functions

Signed-off-by: Josh Holland
Acked-by: Johannes Sixt

Python's async functions (declared with "async def" rather than "def") were not being displayed in hunk headers.
This commit teaches Git about the async function syntax, and adds tests for the Python userdiff regex.

Not the answer you're looking for? Browse other questions tagged or ask your own question.