11

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?

2
  • Rather than looking at the actual diff, does Git get the merge done correctly? Commented Dec 3, 2016 at 16:12
  • 1
    Git's interpretation produces exactly the same result as yours. Commented Dec 3, 2016 at 16:41

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thats exaclty what i wanted to hear. Thanks for reply.
6

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`?

Comments

5

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.