Subject: Re: git blame breaking on repository with CRLF files

From: Torsten Bögershausen <[email-masked]>
Date: Mon, 10 Aug 2015 22:22:36 +0200

On 2015-08-10 20.48, Junio C Hamano wrote:
> Torsten Bögershausen <[email-masked]> writes:
> 
>> Actually I could reproduce the following:
>> CRLF in repo, CRLF in working tree, core.autocrlf= true.
> 
> What should happen in such a case?  Wouldn't autocrlf=true want to
> strip CRLF down to LF?  Shouldn't it? 

A problem is, that "git status" would report a file as changed,
when it have been committed with CRLF and core.autocrlf was false.

The only "change" that "git status" would trigger on would be the EOL normalization.
So if core.autocrlf would be set true later,
git status reports files as changed.....

Long story short:
Once commited with CRLF, the files will not be normalized in a modern git:

From convert.c:
if (crlf_action == CRLF_GUESS) {
	/*
	 * If the file in the index has any CR in it, do not convert.
	 * This is the new safer autocrlf handling.
	 */
	if (has_cr_in_index(path))
		return 0;
}
---------------------
commit fd6cce9e89ab5ac1125a3b5f5611048ad22379e7
Author: Eyvind Bernhardsen <[email-masked]>
Date:   Wed May 19 22:43:10 2010 +0200

    Add per-repository eol normalization

    Change the semantics of the "crlf" attribute so that it enables
    end-of-line normalization when it is set, regardless of "core.autocrlf".

    Add a new setting for "crlf": "auto", which enables end-of-line
    conversion but does not override the automatic text file detection.

    Add a new attribute "eol" with possible values "crlf" and "lf".  When
    set, this attribute enables normalization and forces git to use CRLF or
    LF line endings in the working directory, respectively.

    The line ending style to be used for normalized text files in the
    working directory is set using "core.autocrlf".  When it is set to
    "true", CRLFs are used in the working directory; when set to "input" or
    "false", LFs are used.
-----------------
So "git status" is somewhat improved, but "git blame" is not.
(My feeling/suspicion is that has_cr_in_index() should be replaced
by has_cr_in_latest_commit() to have "git status" consistent
with "git blame", but more analyzes may be needed.)

A different approach could be to ignore the EOL differences
completely in "git blame" (when core.autocrlf is set and the file
is text, or when the "text" attribute is set).

> And if so, "blame" is correct
> to say that you are changing the line endings of all your lines, as
> what you _would_ commit if you were to commit the tracked files in
> your working tree would be different from what is in the index, no?