Nikage
Nikage

Reputation: 588

Why `git blame -w` does not ignore newlines?

So, given a change with a newline changeset

$ git blame -w -L70,71 file

$ git blame -w -M -L70,71 file

This two commands above give me exactly the same output given below:

523cdb67 (Nick Mikhno 2017-05-26 18:00:13 +0300 70)                     <span id="contactPhoneNumberError"
523cdb67 (Nick Mikhno 2017-05-26 18:00:13 +0300 71)                     class="errorSpan"></span>

E.g git blames ME to change the line but I need to ignore newlines in git annotations I want to see the previous user who had actually changed the code and ignore code reformatting.

According to $ git blame --help

-w
    Ignore whitespace when comparing the parent’s version and the child’s to find where the lines came from.


-M|<num>|
    Detect moved or copied lines within a file. When a commit moves or copies a block of lines (e.g. the original file has A and then B, and the commit changes it to B and then A), the traditional blame algorithm notices only half of the movement and typically blames the lines that were moved up (i.e. B) to the parent and assigns blame to the lines that were moved down (i.e. A) to the child commit. With this option, both groups of lines are blamed on the parent by running extra passes of inspection.

    <num> is optional but it is the lower bound on the number of alphanumeric characters that Git must detect as moving/copying within a file for it to associate those lines with the parent commit. The default value is 20.

Tell me please, what am I wrong at?

Upvotes: 1

Views: 879

Answers (2)

Justin Howard
Justin Howard

Reputation: 5643

Let's say you have the file:

Hello world!

Then run

> git blame hello.txt
^dd5c453 (User1 2017-05-26 13:50:54 -0700 1) Hello world!

Now User2 comes along and adds extra spaces

> git blame hello.txt
fdd9abbe (User2 2017-05-26 13:51:50 -0700 1) Hello     world!

> git blame -w hello.txt
^dd5c453 (User1 2017-05-26 13:50:54 -0700 1) Hello     world!

You can see that using the -w flag ignores the spaces that User2 added. The problem is that each line is evaluated separately for the blame command. That means that even if we use -w, splitting or joining lines always changes the blamed user.

> git blame -w hello.txt
c0c338a5 (User3 2017-05-26 13:55:52 -0700 1) Hello
c0c338a5 (User3 2017-05-26 13:55:52 -0700 2) world!

It's the same for the -M flag. Splitting a line isn't considered a move because git sees the combined line as different data from the two split lines. You could think of it as deleting the combined line and adding two new lines.

So how do you find the original author if blame doesn't work? I often use git log --follow -p hello.txt. This will show you every commit that changed hello.txt and the full diff for each change.

commit c0c338a5bdd99c2edc24541da0a9262d654e9962
Author: User3 <[email protected]>
Date:   Fri May 26 13:55:52 2017 -0700

    commit3

diff --git a/hello.txt b/hello.txt
index 84a0ce0..b85a64c 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,2 @@
-Hello     world!
+Hello
+world!

commit fdd9abbe78fdcbbea3f4acf812e2f5e9867e33f1
Author: User2 <[email protected]>
Date:   Fri May 26 13:51:50 2017 -0700

    commit 2

diff --git a/hello.txt b/hello.txt
index cd08755..84a0ce0 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1 @@
-Hello world!
+Hello     world!

commit dd5c453d7788bedc05eb5665b2dc5454d7a83291
Author: User1 <[email protected]>
Date:   Fri May 26 13:50:54 2017 -0700

    Commit 1

diff --git a/hello.txt b/hello.txt
new file mode 100644
index 0000000..cd08755
--- /dev/null
+++ b/hello.txt
@@ -0,0 +1 @@
+Hello world!

Upvotes: 1

eftshift0
eftshift0

Reputation: 30212

Doesn't look like "code reformatting". You had a single line with, say, 2 words, after revision X you have two lines, one with first word, second line with second word. It's two lines that are different (in content) from the original line. So even with -w you will get those two lines added on the same revision. -w does not imply that new line breaks won't be considered. It's about EOL format changes (windows, UNIX) not being considered as a difference.

Upvotes: 0

Related Questions