8

The problem occurs when trying to diff blocks with same structure commonly appears in html/css for me. Example: Initial commit

Now lets add new param to "someblock" and new class "someotherblock". result

Expected result:

 1  1 .someblock
 2  2    height:100%;
    3+   width:100%;
 3  4 }
    5+.someotherblock{
    6+   height:100%;
    7+}  

Is there any way to make git undestand "logic" of the changes?

3 Answers3

10

It's important to realize that Git does not, and really can not, show you exactly what you did. (Maybe you added the braces first, then added the contents, in that order, in which case to show you what you did it would have to say "first add both braces, then add the contents in between".) Instead, Git simply produces a minimal1 set of instructions that tell a computer how to change "what was there before" to "what should be there now".

The Git programmers try to make the "understandable to computer" instructions somewhat sensible to humans as well, but the answer to this:

Is there any way to make git understand "logic" of the changes?

is "no".

The patience diff (see Gira's answer) can help for some cases, particularly those where Git synchronizes on lines consisting solely of open or close braces and the like.

Git 2.9 added a so-called "compaction heuristic" (described rather lightly here) but it requires a blank line above the changed region. That phrase, "a blank line above", means a blank line, and above: the compaction heuristic doesn't believe the top of a file suffices (although in my opinion it should believe this). The compaction heuristic makes a bigger difference, although for me, the idea of twisting the source just to make the VCS display better diffs is ... annoying, at least.


1"Minimal" in the sense of the fewest possible "delete X" and "add Y" instructions. Git does not take into account the lengths of X and Y, which are typically lines, although Git does have word-oriented diff as well. Ties—where Git could say "delete four lines here and add four there" and move the four around, up or down, get broken in favor of "furthest down" due to the algorithm used, which is why the compaction heuristic only tries to shift up.

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775
5

git diff --histogram is what you're looking for. It will display changes like this in a more human-readable way. It solves the problem of git diff showing brackets (curly braces) "wrong".

See What's the difference between `git diff --patience` and `git diff --histogram`?

Community
  • 1
  • 1
Will Sheppard
  • 3,272
  • 2
  • 31
  • 41
3

You can try to call for a quick test:

git diff --patience

Or set the patience option globally for all diffs:

git config --global diff.algorithm patience

This will take more time to generate the diffs but should generate a nicer output.

Dima
  • 394
  • 3
  • 10