summaryrefslogtreecommitdiff
path: root/builtin/clean.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/clean.c')
-rw-r--r--builtin/clean.c83
1 files changed, 53 insertions, 30 deletions
diff --git a/builtin/clean.c b/builtin/clean.c
index 4ca12bc0c0..687ab473c2 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -162,7 +162,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
if ((force_flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
is_nonbare_repository_dir(path)) {
if (!quiet) {
- quote_path_relative(path->buf, prefix, &quoted);
+ quote_path(path->buf, prefix, &quoted, 0);
printf(dry_run ? _(msg_would_skip_git_dir) : _(msg_skip_git_dir),
quoted.buf);
}
@@ -177,7 +177,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
res = dry_run ? 0 : rmdir(path->buf);
if (res) {
int saved_errno = errno;
- quote_path_relative(path->buf, prefix, &quoted);
+ quote_path(path->buf, prefix, &quoted, 0);
errno = saved_errno;
warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
@@ -202,7 +202,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
if (remove_dirs(path, prefix, force_flag, dry_run, quiet, &gone))
ret = 1;
if (gone) {
- quote_path_relative(path->buf, prefix, &quoted);
+ quote_path(path->buf, prefix, &quoted, 0);
string_list_append(&dels, quoted.buf);
} else
*dir_gone = 0;
@@ -210,11 +210,11 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
} else {
res = dry_run ? 0 : unlink(path->buf);
if (!res) {
- quote_path_relative(path->buf, prefix, &quoted);
+ quote_path(path->buf, prefix, &quoted, 0);
string_list_append(&dels, quoted.buf);
} else {
int saved_errno = errno;
- quote_path_relative(path->buf, prefix, &quoted);
+ quote_path(path->buf, prefix, &quoted, 0);
errno = saved_errno;
warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
@@ -238,7 +238,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
*dir_gone = 1;
else {
int saved_errno = errno;
- quote_path_relative(path->buf, prefix, &quoted);
+ quote_path(path->buf, prefix, &quoted, 0);
errno = saved_errno;
warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
@@ -266,7 +266,7 @@ static void pretty_print_dels(void)
struct column_options copts;
for_each_string_list_item(item, &del_list) {
- qname = quote_path_relative(item->string, NULL, &buf);
+ qname = quote_path(item->string, NULL, &buf, 0);
string_list_append(&list, qname);
}
@@ -667,7 +667,7 @@ static int filter_by_patterns_cmd(void)
if (!confirm.len)
break;
- memset(&dir, 0, sizeof(dir));
+ dir_init(&dir);
pl = add_pattern_list(&dir, EXC_CMDL, "manual exclude");
ignore_list = strbuf_split_max(&confirm, ' ', 0);
@@ -698,7 +698,7 @@ static int filter_by_patterns_cmd(void)
}
strbuf_list_free(ignore_list);
- clear_directory(&dir);
+ dir_clear(&dir);
}
strbuf_release(&confirm);
@@ -753,7 +753,7 @@ static int ask_each_cmd(void)
for_each_string_list_item(item, &del_list) {
/* Ctrl-D should stop removing files */
if (!eof) {
- qname = quote_path_relative(item->string, NULL, &buf);
+ qname = quote_path(item->string, NULL, &buf, 0);
/* TRANSLATORS: Make sure to keep [y/N] as is */
printf(_("Remove %s [y/N]? "), qname);
if (git_read_line_interactively(&confirm) == EOF) {
@@ -923,13 +923,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, builtin_clean_usage,
0);
- memset(&dir, 0, sizeof(dir));
- if (ignored_only)
- dir.flags |= DIR_SHOW_IGNORED;
-
- if (ignored && ignored_only)
- die(_("-x and -X cannot be used together"));
-
+ dir_init(&dir);
if (!interactive && !dry_run && !force) {
if (config_set)
die(_("clean.requireForce set to true and neither -i, -n, nor -f given; "
@@ -946,6 +940,13 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
+ if (ignored && ignored_only)
+ die(_("-x and -X cannot be used together"));
+ if (!ignored)
+ setup_standard_excludes(&dir);
+ if (ignored_only)
+ dir.flags |= DIR_SHOW_IGNORED;
+
if (argc) {
/*
* Remaining args implies pathspecs specified, and we should
@@ -954,15 +955,41 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
remove_directories = 1;
}
- if (remove_directories)
- dir.flags |= DIR_SHOW_IGNORED_TOO | DIR_KEEP_UNTRACKED_CONTENTS;
+ if (remove_directories && !ignored_only) {
+ /*
+ * We need to know about ignored files too:
+ *
+ * If (ignored), then we will delete ignored files as well.
+ *
+ * If (!ignored), then even though we not are doing
+ * anything with ignored files, we need to know about them
+ * so that we can avoid deleting a directory of untracked
+ * files that also contains an ignored file within it.
+ *
+ * For the (!ignored) case, since we only need to avoid
+ * deleting ignored files, we can set
+ * DIR_SHOW_IGNORED_TOO_MODE_MATCHING in order to avoid
+ * recursing into a directory which is itself ignored.
+ */
+ dir.flags |= DIR_SHOW_IGNORED_TOO;
+ if (!ignored)
+ dir.flags |= DIR_SHOW_IGNORED_TOO_MODE_MATCHING;
+
+ /*
+ * Let the fill_directory() machinery know that we aren't
+ * just recursing to collect the ignored files; we want all
+ * the untracked ones so that we can delete them. (Note:
+ * we could also set DIR_KEEP_UNTRACKED_CONTENTS when
+ * ignored_only is true, since DIR_KEEP_UNTRACKED_CONTENTS
+ * only has effect in combination with DIR_SHOW_IGNORED_TOO. It makes
+ * the code clearer to exclude it, though.
+ */
+ dir.flags |= DIR_KEEP_UNTRACKED_CONTENTS;
+ }
if (read_cache() < 0)
die(_("index file corrupt"));
- if (!ignored)
- setup_standard_excludes(&dir);
-
pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
for (i = 0; i < exclude_list.nr; i++)
add_pattern(exclude_list.items[i].string, "", 0, pl, -(i+1));
@@ -994,11 +1021,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
string_list_append(&del_list, rel);
}
- for (i = 0; i < dir.nr; i++)
- free(dir.entries[i]);
-
- for (i = 0; i < dir.ignored_nr; i++)
- free(dir.ignored[i]);
+ dir_clear(&dir);
if (interactive && del_list.nr > 0)
interactive_main_loop();
@@ -1024,19 +1047,19 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
if (remove_dirs(&abs_path, prefix, rm_flags, dry_run, quiet, &gone))
errors++;
if (gone && !quiet) {
- qname = quote_path_relative(item->string, NULL, &buf);
+ qname = quote_path(item->string, NULL, &buf, 0);
printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
}
} else {
res = dry_run ? 0 : unlink(abs_path.buf);
if (res) {
int saved_errno = errno;
- qname = quote_path_relative(item->string, NULL, &buf);
+ qname = quote_path(item->string, NULL, &buf, 0);
errno = saved_errno;
warning_errno(_(msg_warn_remove_failed), qname);
errors++;
} else if (!quiet) {
- qname = quote_path_relative(item->string, NULL, &buf);
+ qname = quote_path(item->string, NULL, &buf, 0);
printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
}
}