Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git diff algorithm that does not rip functions apart? (language-aware diff)

Is it possible to configure git diff to respect indentation and syntax? I am not talking about ignoring indentation and spaces, but rather to use blank lines, indentation levels and possibly brackets, to help matching the old lines to new lines.

E.g. git diff often cuts through functions and their docblock, like this:

 class C {     /** +   * Goes to the bar. +   */ +  function bar() { +    return 'bar'; +  } + +  /**     * Gets your foo up to date.     */    function foo() { 

When I would prefer

 class C { + +  /** +   * Goes to the bar. +   */ +  function bar() { +    return 'bar'; +  }     /**     * Gets your foo up to date.     */    function foo() { 

In this example it is still quite harmless, but there are examples where functions and their docblock are really ripped apart due to the greedy and naive diff implementation.

Note: I already configured *.php diff=php in ~/.gitattributes.

EDIT: Another example: Here git diff mixes a property docblock with a method docblock:

   /** -   * @var int +   * @param string $str     */ 
like image 756
donquixote Avatar asked Jun 11 '14 12:06

donquixote


People also ask

What algorithm does git diff use?

Myers. Myers algorithm was developed by Myers (1986). In the git diff command, this algorithm is used as the default. The operation of this algorithm traces the two primary identical sequences recursively with the least edited script.

What is patience diff?

The first thing to note is that patience diff is not a diff algorithm in and of itself. What it really is is a method of matching up lines in two versions of a document in order to break them into smaller pieces, before using an actual diff algorithm like Myers on those pieces.

What is the default git diff tool?

The default Diff Tool is vimdiff. Specifying a Diff Tool affects the git difftool command. The command git diff still performs diffing on the command-line.

How do I check my git diff tool?

Type git config diff. tool winmerge . Verify it worked by typing git difftool . Get rid of the prompt typing git config --global difftool.


2 Answers

I do not know how to do that in git alone, but there is at least one commercial tool (i.e. it costs money) which deals with that kind of problems, called SemanticMerge.

It can handle quite a lot of cool cases, and supports C#, Java, and partially C. You can configure git to use it as merge tool.

(I'm not affiliated.)

like image 128
henko Avatar answered Sep 21 '22 08:09

henko


First of all use a more sophisticated diff algorithm like:

git config --global diff.algorithm histogram 

Then there are also semantic diff tools like https://github.com/GumTreeDiff/gumtree whose algorithm has also been implemented in clang-diff: https://github.com/krobelus/clang-diff-playground

like image 21
Trass3r Avatar answered Sep 18 '22 08:09

Trass3r