git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [BUG] diff and blame difference

From
Junio C Hamano <gitster@pobox.com>
Date
Jul 26, 2011, 19:25 UTC
Message-ID
<7vzkk0q1xc.fsf@alter.siamese.dyndns.org>
In-Reply-To
<4E2ECABD.7050601@gmail.com>

You need to realize that diff is to express changes as deletion and insertion for humans, while blame is not about expressing changes, but showing the origin of each line.

An example. Imagine you have a file with ten lines (whose contents you will call A, B, C, ..., J). Starting from this initial state, if you make the first three lines to "X B Y", think about what happens.

Most likely, "diff" would give you a single hunk that says "you deleted A B C and then inserted X B Y", making the result look as if B was added by your change.

But that is not the only possible output "diff" could produce. It would also be a valid output if it instead showed two hunks. One hunk would delete A from the first line and add X in its place, and the other hunk would delete C from the third line and add Y in its place. But "git diff" would not do that, in order to make it more readable for humans, these adjacent changes that _could_ be in separate hunks are coalesced into a single hunk.

But "blame" is not constrained by the requirement to show a readable "patch" to humans. It is allowed to, and it does, see this change through, notice and show that B stayed from the older version. Only lines X and Y are new.

Instead of "git --git-dir=D:\src\git\.git diff-tree -p", run it with zero lines of context and you will see lines 184 and 215 indeed stayed from the previous version, which exactly explains why you thought 184 was added by looking at the output of "diff". You can tell that in fact the previous version already had that contents there by looking at "show -U0" output.

And that is what "blame" told you.

Another example that you may not have noticed with just "blame", but would have noticed if you gave it -M or -C option is this.

Starting from the same ten lines, If you move the first three lines and tuck them at the end after J, diff needs to say "remove the first three lines" and then "add these three lines at the end". There is no way for diff to say "these three lines were moved". If you look at "diff" output, you would think "the last three lines A B C were added", while "blame" can see it through and can say "A B C stayed from the beginning".

Previous: Semyon Kirnosenko
Message 2 of 2 in “[BUG] diff and blame difference”
  1. Semyon KirnosenkoJul 26, 2011
  2. Junio C HamanoJul 26, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.