Commit f6343036aa4d7e3805a44832b566b531271c1c6d

Stefan Sperling 2021-06-22T20:00:44

new -I option for 'got status' to show files which match an ignore pattern

diff --git a/got/got.1 b/got/got.1
index 8e0440c..ea184ea 100644
--- a/got/got.1
+++ b/got/got.1
@@ -672,6 +672,8 @@ The options for
 .Cm got status
 are as follows:
 .Bl -tag -width Ds
+.It Fl I
+Show unversioned files even if they match an ignore pattern.
 .It Fl s Ar status-codes
 Only show files with a modification status matching any of the
 single-character status codes contained in the
diff --git a/got/got.c b/got/got.c
index 097226d..3af8d5f 100644
--- a/got/got.c
+++ b/got/got.c
@@ -4430,8 +4430,8 @@ cmd_diff(int argc, char *argv[])
 		if (error)
 			goto done;
 
-		error = got_worktree_status(worktree, &paths, repo, print_diff,
-		    &arg, check_cancelled, NULL);
+		error = got_worktree_status(worktree, &paths, repo, 0,
+		    print_diff, &arg, check_cancelled, NULL);
 		free(id_str);
 		got_pathlist_free(&paths);
 		goto done;
@@ -5119,7 +5119,7 @@ done:
 __dead static void
 usage_status(void)
 {
-	fprintf(stderr, "usage: %s status [-s status-codes ] [path ...]\n",
+	fprintf(stderr, "usage: %s status [-I] [-s status-codes ] [path ...]\n",
 	    getprogname());
 	exit(1);
 }
@@ -5157,12 +5157,15 @@ cmd_status(int argc, char *argv[])
 	char *cwd = NULL, *status_codes = NULL;;
 	struct got_pathlist_head paths;
 	struct got_pathlist_entry *pe;
-	int ch, i;
+	int ch, i, no_ignores = 0;
 
 	TAILQ_INIT(&paths);
 
-	while ((ch = getopt(argc, argv, "s:")) != -1) {
+	while ((ch = getopt(argc, argv, "Is:")) != -1) {
 		switch (ch) {
+		case 'I':
+			no_ignores = 1;
+			break;
 		case 's':
 			for (i = 0; i < strlen(optarg); i++) {
 				switch (optarg[i]) {
@@ -5224,8 +5227,8 @@ cmd_status(int argc, char *argv[])
 	if (error)
 		goto done;
 
-	error = got_worktree_status(worktree, &paths, repo, print_status,
-	    status_codes, check_cancelled, NULL);
+	error = got_worktree_status(worktree, &paths, repo, no_ignores,
+	    print_status, status_codes, check_cancelled, NULL);
 done:
 	TAILQ_FOREACH(pe, &paths, entry)
 		free((char *)pe->path);
@@ -9536,7 +9539,7 @@ cmd_histedit(int argc, char *argv[])
 				if (error)
 					goto done;
 				error = got_worktree_status(worktree, &paths,
-				    repo, check_local_changes, &have_changes,
+				    repo, 0, check_local_changes, &have_changes,
 				    check_cancelled, NULL);
 				got_pathlist_free(&paths);
 				if (error) {
@@ -9924,7 +9927,7 @@ cmd_stage(int argc, char *argv[])
 		goto done;
 
 	if (list_stage)
-		error = got_worktree_status(worktree, &paths, repo,
+		error = got_worktree_status(worktree, &paths, repo, 0,
 		    print_stage, NULL, check_cancelled, NULL);
 	else {
 		cpa.patch_script_file = patch_script_file;
diff --git a/include/got_worktree.h b/include/got_worktree.h
index 9246dbd..5cf8592 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -171,7 +171,7 @@ typedef const struct got_error *(*got_worktree_status_cb)(void *,
  * a path, and a corresponding status code.
  */
 const struct got_error *got_worktree_status(struct got_worktree *,
-    struct got_pathlist_head *, struct got_repository *,
+    struct got_pathlist_head *, struct got_repository *, int no_ignores,
     got_worktree_status_cb, void *, got_cancel_cb cancel_cb, void *);
 
 /*
diff --git a/lib/worktree.c b/lib/worktree.c
index 8fda195..c6a9ee6 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -3734,7 +3734,7 @@ done:
 const struct got_error *
 got_worktree_status(struct got_worktree *worktree,
     struct got_pathlist_head *paths, struct got_repository *repo,
-    got_worktree_status_cb status_cb, void *status_arg,
+    int no_ignores, got_worktree_status_cb status_cb, void *status_arg,
     got_cancel_cb cancel_cb, void *cancel_arg)
 {
 	const struct got_error *err = NULL;
@@ -3748,7 +3748,8 @@ got_worktree_status(struct got_worktree *worktree,
 
 	TAILQ_FOREACH(pe, paths, entry) {
 		err = worktree_status(worktree, pe->path, fileindex, repo,
-			status_cb, status_arg, cancel_cb, cancel_arg, 0, 0);
+			status_cb, status_arg, cancel_cb, cancel_arg,
+			no_ignores, 0);
 		if (err)
 			break;
 	}
diff --git a/regress/cmdline/status.sh b/regress/cmdline/status.sh
index 551a962..8c6c24e 100755
--- a/regress/cmdline/status.sh
+++ b/regress/cmdline/status.sh
@@ -581,6 +581,33 @@ test_status_cvsignore() {
 	ret="$?"
 	if [ "$ret" != "0" ]; then
 		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	cat > $testroot/stdout.expected <<EOF
+?  .cvsignore
+?  epsilon/.cvsignore
+?  epsilon/bar
+?  epsilon/boo
+?  epsilon/foo
+?  epsilon/moo
+?  epsilon/new/foo
+?  foo
+?  foop
+EOF
+	(cd $testroot/wt && got status -I > $testroot/stdout)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "got status failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
 	fi
 	test_done "$testroot" "$ret"
 }
@@ -630,6 +657,33 @@ test_status_gitignore() {
 	ret="$?"
 	if [ "$ret" != "0" ]; then
 		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	cat > $testroot/stdout.expected <<EOF
+?  .gitignore
+?  a/b/c/foo
+?  a/b/c/zoo
+?  barp
+?  epsilon/bar
+?  epsilon/boo
+?  epsilon/moo
+?  foo
+?  foop
+EOF
+	(cd $testroot/wt && got status -I > $testroot/stdout)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "got status failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
 	fi
 	test_done "$testroot" "$ret"
 }