Re: [PATCH v2] Add support for -i/--interactive to git-clean
From: Eric Sunshine <hidden>
Date: 2016-06-15 22:57:03
Possibly related (same subject, not in this thread)
- 2016-06-15 · Re: [PATCH v2] Add support for -i/--interactive to git-clean · Matthieu Moy <hidden>
- 2016-06-15 · Re: [PATCH v2] Add support for -i/--interactive to git-clean · Junio C Hamano <hidden>
- 2016-06-15 · Re: [PATCH v2] Add support for -i/--interactive to git-clean · Matthieu Moy <hidden>
- 2016-06-15 · Re: [PATCH v2] Add support for -i/--interactive to git-clean · Jiang Xin <hidden>
On Sat, Apr 27, 2013 at 12:13 PM, Jiang Xin [off-list ref] wrote:
quoted hunk ↗ jump to hunk
--- a/builtin/clean.c +++ b/builtin/clean.c@@ -257,26 +261,92 @@ int cmd_clean(int argc, const char **argv, const char *prefix) } if (S_ISDIR(st.st_mode)) { - strbuf_addstr(&directory, ent->name); if (remove_directories || (matches == MATCHED_EXACTLY)) { - if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone)) - errors++; - if (gone && !quiet) { - qname = quote_path_relative(directory.buf, directory.len, &buf, prefix); - printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname); - } + string_list_append(&dels, ent->name); } - strbuf_reset(&directory); } else { if (pathspec && !matches) continue; - res = dry_run ? 0 : unlink(ent->name); + string_list_append(&dels, ent->name); + } + } + + if (interactive && dels.nr > 0 && !dry_run && isatty(0) && isatty(1)) { + struct strbuf confirm = STRBUF_INIT; + + while (1) { + struct strbuf **prefix_list, **prefix_list_head; + + /* dels list may become empty when we run string_list_remove_empty_items latter */
s/latter/later/
+ if (!dels.nr)
+ break;
+
+ for_each_string_list_item(item, &dels) {
+ qname = quote_path_relative(item->string, -1, &buf, prefix);
+ printf(_(msg_would_remove), qname);
+ }
+
+ printf(_("Remove (press enter to confirm or input items you want to keep)? "));
+ strbuf_getline(&confirm, stdin, '\n');
+ strbuf_trim(&confirm);
+
+ if (!confirm.len)
+ break;
+
+ printf("\n");
+
+ prefix_list_head = strbuf_split_buf(confirm.buf, confirm.len, ' ', 0);
+ for (prefix_list = prefix_list_head; *prefix_list; *prefix_list++)
+ {
+ int prefix_matched = 0;
+
+ strbuf_trim(*prefix_list);
+ if (!(*prefix_list)->len)
+ continue;
+
+ for_each_string_list_item(item, &dels) {
+ if (!strncasecmp(item->string, (*prefix_list)->buf, (*prefix_list)->len)) {
+ *item->string = '\0';
+ prefix_matched++;
+ }
+ }
+ if (!prefix_matched) {
+ warning(_("Cannot find items start with the given prefix: %s"), (*prefix_list)->buf);s/start/starting/ [...or...] s/items start with the given prefix/items prefixed by/
+ printf("\n");
+ } else {
+ string_list_remove_empty_items(&dels, 0);
+ }
+ }
+
+ strbuf_reset(&confirm);
+ strbuf_list_free(prefix_list_head);
+ }
+ strbuf_release(&confirm);
+ }
+
+ for_each_string_list_item(item, &dels) {
+ struct stat st;
+
+ if (lstat(item->string, &st))
+ continue;
+
+ if (S_ISDIR(st.st_mode)) {
+ strbuf_addstr(&directory, item->string);
+ if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone))
+ errors++;
+ if (gone && !quiet) {
+ qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
+ printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
+ }
+ strbuf_reset(&directory);
+ } else {
+ res = dry_run ? 0 : unlink(item->string);
if (res) {
- qname = quote_path_relative(ent->name, -1, &buf, prefix);
+ qname = quote_path_relative(item->string, -1, &buf, prefix);
warning(_(msg_warn_remove_failed), qname);
errors++;
} else if (!quiet) {
- qname = quote_path_relative(ent->name, -1, &buf, prefix);
+ qname = quote_path_relative(item->string, -1, &buf, prefix);
printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
}
}