Subject: git status reports file modified when only line-endings have changed (was git diff --quiet exits with 1 on clean tree with CRLF conversions)

From: Mike Crowe <[email-masked]>
Date: Thu, 2 Mar 2017 15:38:17 +0000

On Tuesday 28 February 2017 at 19:06:44 +0100, Torsten Bögershausen wrote:
> My understanding is that git diff --quiet should be quiet, when
> git add will not do anything (but the file is "touched".
> The touched means that Git will detect e.g a new mtime or inode
> or file size when doing lstat().

Does the same apply to "git status"?

If so, then whilst investigating the "git diff --quiet" problems in this
thread I've found a similar bug with "git status". It reports the file has
modifications even if only the line-endings have changed, and issuing "git
add" causes the perceived modification to disappear.

It can be very confusing for users if "git status" reports a modification
but for "git diff" to claim that the files are identical.

This bug is still reproducible even with the fix from
https://public-inbox.org/git/[email-masked]/T/#m67cbfad1f2efe721f0c2afac2a1523b743bb57ca

Here's the test case. Test 3 is the part that currently fails:

commit de5f3f1d9161cdd46342689abe38a046fc71850e
Author: Mike Crowe <[email-masked]>
Date:   Sat Feb 25 09:28:37 2017 +0000

    status: Add tests for status output when file line endings change

diff --git a/t/t7518-status-eol-change.sh b/t/t7518-status-eol-change.sh
new file mode 100755
index 0000000..e18186f
--- /dev/null
+++ b/t/t7518-status-eol-change.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# Copyright (c) 2017 Mike Crowe
+#
+
+test_description='git status with files that require CRLF conversion'
+
+. ./test-lib.sh
+
+cat >expected_no_change <<EOF
+On branch master
+nothing to commit, working tree clean
+EOF
+
+test_expect_success setup '
+	echo "* text=auto" > .gitattributes &&
+	printf "Hello\r\nWorld\r\n" > crlf.txt &&
+	printf "expected_no_change\nactual\n" > .gitignore &&
+	git add .gitignore .gitattributes crlf.txt &&
+	git commit -m "initial"
+'
+test_expect_success 'git status reports no change if file regenerated' '
+	printf "Hello\r\nWorld\r\n" > crlf.txt &&
+	git status >actual &&
+	test_cmp expected_no_change actual
+'
+test_expect_success 'git status reports no change if line endings change' '
+	printf "Hello\nWorld\n" > crlf.txt &&
+	git status >actual &&
+	test_cmp expected_no_change actual
+'
+test_expect_success 'git status reports no change if line ending change is staged' '
+	git add crlf.txt &&
+	git status >actual &&
+	test_cmp expected_no_change actual
+'
+test_done