Commit 0dbc22715b295b0b4fd65dfdc2ea1cd9c16083a7

Stefan Sperling 2019-02-05T16:16:13

make 'got status' detect obstructed files

diff --git a/got/got.1 b/got/got.1
index 374ed5e..4918b98 100644
--- a/got/got.1
+++ b/got/got.1
@@ -115,6 +115,7 @@ using the following status codes:
 .Bl -column YXZ description
 .It M Ta modified file
 .It ! Ta versioned file was expected on disk but is missing
+.It ~ Ta versioned file is obstructed by a non-regular file
 .It ? Ta unversioned item not tracked by
 .Nm
 .El
diff --git a/include/got_worktree.h b/include/got_worktree.h
index 58867ae..879b57c 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -25,6 +25,7 @@ struct got_worktree;
 #define GOT_STATUS_MODIFIY	'M'
 #define GOT_STATUS_MISSING	'!'
 #define GOT_STATUS_UNVERSIONED	'?'
+#define GOT_STATUS_OBSTRUCTED	'~'
 
 /*
  * Attempt to initialize a new work tree on disk.
diff --git a/lib/worktree.c b/lib/worktree.c
index 6f599b3..063b75f 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -936,8 +936,10 @@ get_file_status(unsigned char *status, struct got_fileindex_entry *ie,
 	if (lstat(abspath, &sb) == -1)
 		return got_error_from_errno();
 
-	if (!S_ISREG(sb.st_mode))
+	if (!S_ISREG(sb.st_mode)) {
+		*status = GOT_STATUS_OBSTRUCTED;
 		return NULL;
+	}
 
 	if (ie->ctime_sec == sb.st_ctime &&
 	    ie->ctime_nsec == sb.st_ctimensec &&
diff --git a/regress/cmdline/status.sh b/regress/cmdline/status.sh
index 787e05f..d6d36bc 100755
--- a/regress/cmdline/status.sh
+++ b/regress/cmdline/status.sh
@@ -125,6 +125,33 @@ function test_status_subdir_no_mods2 {
 	test_done "$testroot" "0"
 }
 
+function test_status_obstructed {
+	local testroot=`test_init status_obstructed`
+
+	got checkout $testroot/repo $testroot/wt > /dev/null
+	if [ "$?" != "0" ]; then
+		test_done "$testroot" "$?"
+		return 1
+	fi
+
+	rm $testroot/wt/epsilon/zeta
+	mkdir $testroot/wt/epsilon/zeta
+
+	echo '~  epsilon/zeta' > $testroot/stdout.expected
+
+	(cd $testroot/wt && got status > $testroot/stdout)
+
+	cmp $testroot/stdout.expected $testroot/stdout
+	if [ "$?" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$?"
+		return 1
+	fi
+
+	test_done "$testroot" "0"
+}
+
 run_test test_status_basic
 run_test test_status_subdir_no_mods
 run_test test_status_subdir_no_mods2
+run_test test_status_obstructed