24

This has been bugging me for a while and searching has yielded no hints.

Issue:

When I do a git diff on a PHP file containing a Class, each hunk description has the class name with no mention of the method name.

For example:

@@ -351,7 +351,7 @@ class Session
             $form->setError($field, $subpassValid['msg']);
       }

       // E-Mail address error checking
       $field = "email";  //Use field name for email
-       if(!isset($subemail) || strlen($subemail = trim($subemail)) == 0){
+       if(!$subemail || strlen($subemail = trim($subemail)) == 0){
          $form->setError($field, "* Email not entered");
@@ -373,7 +373,7 @@ class Session
...

Question:

Is there a way to tell git to show method names instead of/along side of the class name?

Edit:

Additional Information:

diff version: 2.8.1
git version: 1.7.6 (from the git-core PPA)
OS: Ubuntu 9.10

I originally had git version 1.7.0.4 from the stock Ubuntu repos, but updated it hoping that it was a bug. Unfortunately that didn't solve the issue.

Edit2:

After more testing, it appears that if the function declaration is indented at all (with either spaces or tabs) git diff doesn't pick up the function name. This appears to be a bug in git.

Tarek Fadel
  • 1,909
  • 1
  • 14
  • 22
  • 1
    Some more info here: http://stackoverflow.com/questions/2783086/how-does-git-diff-generate-hunk-descriptions – CodeCaster Sep 08 '11 at 07:35
  • 1
    Looks like we have a bug. [It should work exactly like you want it to.](https://github.com/git/git/blob/master/userdiff.c#L92) – sanmai Sep 08 '11 at 08:10
  • What is the exact filename you display the diff of? – hakre Sep 08 '11 at 08:52
  • @hakre The behavior I am referring to is uniform across the board. It happens when I call `git diff session.php` (from which the example is taken from) or `git diff master` or just `git diff --staged`. – Tarek Fadel Sep 08 '11 at 09:19

3 Answers3

23

If you find yourself having this issue, it might be due to the fact that git lets diff define the hunk header. If you want to force git to use its predefined ones for PHP place the following line in either .gitattributes in the root folder of your git repository or the .git/info/attributes file in your repository:

*.php diff=php

(Other languages are similarly supported. A list of the built in patterns is available in the documentation.)

Setting this Globally

It should be possible to globally set this by doing the following in git version >= 1.4

  1. Put line(s) in ~/.gitattributes
  2. Run git config --global core.attributesfile "~/.gitattributes"

Or if you want to set this globally

  1. Put line(s) into /etc/gitattributes

Warning: If you personally set this globally, your peers may get different results when running git diff since they won't checkout a copy of .gitattributes with the repository.

Loren
  • 9,783
  • 4
  • 39
  • 49
Tarek Fadel
  • 1,909
  • 1
  • 14
  • 22
8

I don't quite understand why it doesn't work the way it should.

As a temporary solution, add the following to .gitattributes:

*.php   diff=phpf

And these lines to .git/config or ~/.gitconfig:

[diff "phpf"]
        xfuncname = "^[\t ]*(((public|protected|private|static)[\t ]+)*function.*)$"

For a permanent solution ask Git developers directly at git@vger.kernel.org mailing list.

sanmai
  • 29,083
  • 12
  • 64
  • 76
  • Doing the above removes that part completely. Using the above example, `class Session` has now disappeared, replaced by nothing. I've added version numbers to the original question if that helps any. – Tarek Fadel Sep 08 '11 at 09:10
  • 3
    I think the `\n` at the end breaks it; it is used somehow to separate regexes and you have only one here. Without that, it worked for me. (The other solution is more elegant though.) – Tgr Dec 01 '11 at 16:15
1

That diff would likely be better with Git 2.19 (Q3 2018), since the userdiff pattern for .php has been updated.

See commit 1ab6316, commit 9992fbd (03 Jul 2018) by Kana Natsuno (kana).
(Merged by Junio C Hamano -- gitster -- in commit d3f0938, 24 Jul 2018)

userdiff: support new keywords in PHP hunk header

Recent version of PHP supports interface, trait, abstract class and final class.
This patch fixes the PHP hunk header regexp to support all of these keywords.


And it does improve with Git 2.30 (Q1 2021):

See commit aff9282 (07 Oct 2020) by Javier Spagnoletti (phansys).
(Merged by Junio C Hamano -- gitster -- in commit a8a49eb, 27 Oct 2020)

userdiff: PHP: catch "abstract" and "final" functions

Helped-by: Johannes Sixt
Signed-off-by: Javier Spagnoletti

PHP permits functions to be defined like

final public function foo() { }
abstract protected function bar() { }  

but our hunk header pattern does not recognize these decorations.

Add "final" and "abstract" to the list of function modifiers.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250