Commit 4a26d3f877326c99bcf462b076800a112319ff6d

Stefan Sperling 2020-10-07T22:37:48

fix a bug where 'got status' showed an unchanged empty file as changed

diff --git a/lib/worktree.c b/lib/worktree.c
index d376968..1c36cc6 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1784,12 +1784,12 @@ get_file_status(unsigned char *status, struct stat *sb,
 			err = got_error_from_errno("fread");
 			goto done;
 		}
-		if (blen == 0) {
+		if (blen - hdrlen == 0) {
 			if (flen != 0)
 				*status = GOT_STATUS_MODIFY;
 			break;
 		} else if (flen == 0) {
-			if (blen != 0)
+			if (blen - hdrlen != 0)
 				*status = GOT_STATUS_MODIFY;
 			break;
 		} else if (blen - hdrlen == flen) {
diff --git a/regress/cmdline/status.sh b/regress/cmdline/status.sh
index 9aca32f..09bd0ff 100755
--- a/regress/cmdline/status.sh
+++ b/regress/cmdline/status.sh
@@ -749,6 +749,59 @@ test_status_status_code() {
 	test_done "$testroot" "$ret"
 }
 
+test_status_empty_file() {
+	local testroot=`test_init status_empty_file`
+
+	got checkout $testroot/repo $testroot/wt > /dev/null
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo -n "" > $testroot/wt/empty
+	(cd $testroot/wt && got add empty >/dev/null)
+
+	echo 'A  empty' > $testroot/stdout.expected
+
+	(cd $testroot/wt && got status > $testroot/stdout)
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got commit -m "empty file" >/dev/null)
+
+	(cd $testroot/wt && got status > $testroot/stdout)
+
+	echo -n > $testroot/stdout.expected
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# update the timestamp; this used to make the file show up as:
+	# M  empty
+	# which should not happen
+	touch $testroot/wt/empty
+
+	(cd $testroot/wt && got status > $testroot/stdout)
+
+	echo -n > $testroot/stdout.expected
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
+	test_done "$testroot" "$ret"
+}
 
 test_parseargs "$@"
 run_test test_status_basic
@@ -766,3 +819,4 @@ run_test test_status_many_paths
 run_test test_status_cvsignore
 run_test test_status_gitignore
 run_test test_status_status_code
+run_test test_status_empty_file