Diff does not know what you did to a file. It only sees the before and the after, and works out a set of insertions and deletions that would turn one into the other. Specifically, it looks for the longest common subsequence, the largest set of lines that appear in both in the same order, and treats everything else as inserted or deleted.

Why the result can surprise you

The catch is that the smallest set of edits is often not unique. When two regions look similar, there can be several equally short ways to explain the change, and the algorithm simply picks one by its internal rules. That is why a diff sometimes:

  • Blames the wrong block. If you add a function that ends with a closing brace, the diff may pair your new brace with an existing one and show the change starting a line off from where you think it did.
  • Splits a moved section. Move a block of code and a line diff does not see a move at all; it sees a deletion in one place and an insertion in another, sometimes broken into pieces that align with unrelated matching lines.
  • Attaches blank or boilerplate lines oddly. Repeated lines like blank lines or } are interchangeable to the algorithm, so it may group them in a way that reads strangely.

Reading them anyway

None of this means the diff is wrong; it is a correct minimal explanation, just not the one that matches your mental model of the edit. The fix is not to fight it but to read it as "one valid way to get from A to B." When a diff looks off, a word or character level view often makes the real change obvious, and for moved code, comparing the two blocks directly is clearer than trusting the alignment. The takeaway is that a diff describes a transformation between two states, not the story of how you got there.

Minimal is not the same as understandable

A diff algorithm optimises for the fewest edits, and that objective has no notion of meaning. The smallest edit script and the clearest explanation of a change are different things, and where they diverge the tool always chooses the first.

This is why a change to a line that resembles its neighbours produces baffling output: the algorithm found a shorter alignment through the surrounding lines, which is correct by its own measure and useless by yours. Adding a closing brace can be reported as changing a different closing brace three lines away.

When a diff is unreadable, change the question rather than the change. Word-level comparison, whitespace insensitivity, or a different base often produce output a human can read — the edits did not change, only what the algorithm was asked to minimise across.