"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
make 'got add' robert-compatible
To:
gameoftrees@openbsd.org
Date:
Tue, 6 Jul 2021 17:08:05 +0200

Download raw body.

Thread
Require the -I option to add ignored files to version control
even when 'got add' is not recursing into directories with -R.

Inspired by robert@ accidentally committing a ./iridium.core file to the
CVS ports tree in spite of "*.core" being on cvs's default ignore list.

ok?

By the way, Got relies on .cvsignore and .gitignore files only at present.
We might want to add a hard-coded default ignore list in a separate patch,
and put patterns like "*.core" on this list.

diff aea75d87862c3ab54d0b8c5e5e280e13efe8ec4a /home/stsp/src/got
blob - cc9598e29205c3fe87df2026697edbe3a56b8e01
file + got/got.1
--- got/got.1
+++ got/got.1
@@ -1125,6 +1125,9 @@ another repository.
 .It Cm add Oo Fl R Oc Oo Fl I Oc Ar path ...
 Schedule unversioned files in a work tree for addition to the
 repository in the next commit.
+By default, files which match a
+.Cm got status
+ignore pattern will not be added.
 .Pp
 The options for
 .Cm got add
@@ -1138,7 +1141,7 @@ will refuse to run if a specified
 .Ar path
 is a directory.
 .It Fl I
-With -R, add files even if they match a
+Add files even if they match a
 .Cm got status
 ignore pattern.
 .El
blob - edd395ed589265482e441455dfb7bdf7047df17a
file + got/got.c
--- got/got.c
+++ got/got.c
@@ -6494,13 +6494,6 @@ cmd_add(int argc, char *argv[])
 	if (error)
 		goto done;
 
-	if (!can_recurse && no_ignores) {
-		error = got_error_msg(GOT_ERR_BAD_PATH,
-		    "disregarding ignores requires -R option");
-		goto done;
-
-	}
-
 	if (!can_recurse) {
 		char *ondisk_path;
 		struct stat sb;
blob - 515ea2335fcce5c7e77172985fe6dc270ac9cf10
file + lib/worktree.c
--- lib/worktree.c
+++ lib/worktree.c
@@ -3269,7 +3269,7 @@ struct diff_dir_cb_arg {
     got_cancel_cb cancel_cb;
     void *cancel_arg;
     /* A pathlist containing per-directory pathlists of ignore patterns. */
-    struct got_pathlist_head ignores;
+    struct got_pathlist_head *ignores;
     int report_unchanged;
     int no_ignores;
 };
@@ -3573,7 +3573,7 @@ status_new(void *arg, struct dirent *de, const char *p
 
 	if (de->d_type != DT_DIR &&
 	    got_path_is_child(path, a->status_path, a->status_path_len)
-	    && !match_ignores(&a->ignores, path))
+	    && !match_ignores(a->ignores, path))
 		err = (*a->status_cb)(a->status_arg, GOT_STATUS_UNVERSIONED,
 		    GOT_STATUS_NO_CHANGE, path, NULL, NULL, NULL, -1, NULL);
 	if (parent_path[0])
@@ -3590,12 +3590,12 @@ status_traverse(void *arg, const char *path, int dirfd
 	if (a->no_ignores)
 		return NULL;
 
-	err = add_ignores(&a->ignores, a->worktree->root_path,
+	err = add_ignores(a->ignores, a->worktree->root_path,
 	    path, dirfd, ".cvsignore");
 	if (err)
 		return err;
 
-	err = add_ignores(&a->ignores, a->worktree->root_path, path,
+	err = add_ignores(a->ignores, a->worktree->root_path, path,
 	    dirfd, ".gitignore");
 
 	return err;
@@ -3603,12 +3603,16 @@ status_traverse(void *arg, const char *path, int dirfd
 
 static const struct got_error *
 report_single_file_status(const char *path, const char *ondisk_path,
-struct got_fileindex *fileindex, got_worktree_status_cb status_cb,
-void *status_arg, struct got_repository *repo, int report_unchanged)
+    struct got_fileindex *fileindex, got_worktree_status_cb status_cb,
+    void *status_arg, struct got_repository *repo, int report_unchanged,
+    struct got_pathlist_head *ignores)
 {
 	struct got_fileindex_entry *ie;
 	struct stat sb;
 
+	if (match_ignores(ignores, path))
+		return NULL;
+
 	ie = got_fileindex_entry_get(fileindex, path, strlen(path));
 	if (ie)
 		return report_file_status(ie, ondisk_path, -1, NULL,
@@ -3667,6 +3671,8 @@ add_ignores_from_parent_paths(struct got_pathlist_head
 				err = NULL; /* traversed everything */
 			break;
 		}
+		if (got_path_is_root_dir(parent_path))
+			break;
 		free(parent_path);
 		parent_path = next_parent_path;
 		next_parent_path = NULL;
@@ -3689,8 +3695,9 @@ worktree_status(struct got_worktree *worktree, const c
 	struct got_fileindex_diff_dir_cb fdiff_cb;
 	struct diff_dir_cb_arg arg;
 	char *ondisk_path = NULL;
+	struct got_pathlist_head ignores;
 
-	TAILQ_INIT(&arg.ignores);
+	TAILQ_INIT(&ignores);
 
 	if (asprintf(&ondisk_path, "%s%s%s",
 	    worktree->root_path, path[0] ? "/" : "", path) == -1)
@@ -3701,10 +3708,17 @@ worktree_status(struct got_worktree *worktree, const c
 		if (errno != ENOTDIR && errno != ENOENT && errno != EACCES &&
 		    errno != ELOOP)
 			err = got_error_from_errno2("open", ondisk_path);
-		else
+		else {
+			if (!no_ignores) {
+				err = add_ignores_from_parent_paths(&ignores,
+				    worktree->root_path, ondisk_path);
+				if (err)
+					goto done;
+			}
 			err = report_single_file_status(path, ondisk_path,
 			    fileindex, status_cb, status_arg, repo,
-			    report_unchanged);
+			    report_unchanged, &ignores);
+		}
 	} else {
 		fdiff_cb.diff_old_new = status_old_new;
 		fdiff_cb.diff_old = status_old;
@@ -3722,16 +3736,17 @@ worktree_status(struct got_worktree *worktree, const c
 		arg.report_unchanged = report_unchanged;
 		arg.no_ignores = no_ignores;
 		if (!no_ignores) {
-			err = add_ignores_from_parent_paths(&arg.ignores,
+			err = add_ignores_from_parent_paths(&ignores,
 			    worktree->root_path, path);
 			if (err)
 				goto done;
 		}
+		arg.ignores = &ignores;
 		err = got_fileindex_diff_dir(fileindex, fd,
 		    worktree->root_path, path, repo, &fdiff_cb, &arg);
 	}
 done:
-	free_ignores(&arg.ignores);
+	free_ignores(&ignores);
 	if (fd != -1 && close(fd) == -1 && err == NULL)
 		err = got_error_from_errno("close");
 	free(ondisk_path);
blob - a7fa11961629003f3de704711ae064f29cfb087b
file + regress/cmdline/add.sh
--- regress/cmdline/add.sh
+++ regress/cmdline/add.sh
@@ -181,7 +181,7 @@ test_add_directory() {
 
 	(cd $testroot/wt && got add -I . > $testroot/stdout 2> $testroot/stderr)
 	ret="$?"
-	echo "got: disregarding ignores requires -R option" \
+	echo "got: adding directories requires -R option" \
 		> $testroot/stderr.expected
 	cmp -s $testroot/stderr.expected $testroot/stderr
 	ret="$?"
@@ -237,6 +237,18 @@ test_add_directory() {
 
 	(cd $testroot/wt && got add tree2/foo > $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
+
+	(cd $testroot/wt && got add -I tree2/foo > $testroot/stdout)
+
 	echo 'A  tree2/foo' > $testroot/stdout.expected
 
 	cmp -s $testroot/stdout.expected $testroot/stdout