Commit a84c0d302fea1f440dfc5b1e70dac59cc50e31f9

Stefan Sperling 2022-03-12T21:30:23

fix 'got status' with an obstructed file given as argument; found by Omar

diff --git a/lib/worktree.c b/lib/worktree.c
index 0b45714..26ce9d0 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -3645,6 +3645,7 @@ worktree_status(struct got_worktree *worktree, const char *path,
 	struct diff_dir_cb_arg arg;
 	char *ondisk_path = NULL;
 	struct got_pathlist_head ignores;
+	struct got_fileindex_entry *ie;
 
 	TAILQ_INIT(&ignores);
 
@@ -3652,6 +3653,14 @@ worktree_status(struct got_worktree *worktree, const char *path,
 	    worktree->root_path, path[0] ? "/" : "", path) == -1)
 		return got_error_from_errno("asprintf");
 
+	ie = got_fileindex_entry_get(fileindex, path, strlen(path));
+	if (ie) {
+		err = report_single_file_status(path, ondisk_path,
+		    fileindex, status_cb, status_arg, repo,
+		    report_unchanged, &ignores, no_ignores);
+		goto done;
+	}
+
 	fd = open(ondisk_path, O_RDONLY | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
 	if (fd == -1) {
 		if (errno != ENOTDIR && errno != ENOENT && errno != EACCES &&
diff --git a/regress/cmdline/status.sh b/regress/cmdline/status.sh
index 9e58172..f96cb55 100755
--- a/regress/cmdline/status.sh
+++ b/regress/cmdline/status.sh
@@ -152,6 +152,16 @@ test_status_obstructed() {
 	ret="$?"
 	if [ "$ret" != "0" ]; then
 		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got status epsilon/zeta > $testroot/stdout)
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
 	fi
 	test_done "$testroot" "$ret"
 }