Make 'got add' always require the -I option in order to add ignored files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
diff --git a/got/got.1 b/got/got.1
index cc9598e..905badf 100644
--- a/got/got.1
+++ b/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
diff --git a/got/got.c b/got/got.c
index edd395e..36887d9 100644
--- a/got/got.c
+++ b/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;
diff --git a/lib/worktree.c b/lib/worktree.c
index 515ea23..88db6fa 100644
--- a/lib/worktree.c
+++ b/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 *parent_path, int dirfd)
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 *ignores,
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 char *path,
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 char *path,
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 char *path,
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);
diff --git a/regress/cmdline/add.sh b/regress/cmdline/add.sh
index a7fa119..0b8274b 100755
--- a/regress/cmdline/add.sh
+++ b/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