зеркало из https://github.com/microsoft/git.git
git-clean: add support for -i/--interactive
Show what would be done and the user must confirm before actually cleaning. Would remove ... Would remove ... Would remove ... Remove [y/n]? Press "y" to start cleaning, and press "n" if you want to abort. Signed-off-by: Jiang Xin <worldhello.net@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
396049e5fb
Коммит
1769600208
|
@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree
|
|||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git clean' [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...
|
||||
'git clean' [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -34,7 +34,13 @@ OPTIONS
|
|||
-f::
|
||||
--force::
|
||||
If the Git configuration variable clean.requireForce is not set
|
||||
to false, 'git clean' will refuse to run unless given -f or -n.
|
||||
to false, 'git clean' will refuse to run unless given -f, -n or
|
||||
-i.
|
||||
|
||||
-i::
|
||||
--interactive::
|
||||
Show what would be done and the user must confirm before actually
|
||||
cleaning.
|
||||
|
||||
-n::
|
||||
--dry-run::
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
#include "quote.h"
|
||||
|
||||
static int force = -1; /* unset */
|
||||
static int interactive;
|
||||
static struct string_list del_list = STRING_LIST_INIT_DUP;
|
||||
|
||||
static const char *const builtin_clean_usage[] = {
|
||||
N_("git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."),
|
||||
N_("git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -143,6 +144,50 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void interactive_main_loop(void)
|
||||
{
|
||||
struct strbuf confirm = STRBUF_INIT;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct string_list_item *item;
|
||||
const char *qname;
|
||||
|
||||
while (del_list.nr) {
|
||||
putchar('\n');
|
||||
for_each_string_list_item(item, &del_list) {
|
||||
qname = quote_path_relative(item->string, NULL, &buf);
|
||||
printf(_(msg_would_remove), qname);
|
||||
}
|
||||
putchar('\n');
|
||||
|
||||
printf(_("Remove [y/n]? "));
|
||||
if (strbuf_getline(&confirm, stdin, '\n') != EOF) {
|
||||
strbuf_trim(&confirm);
|
||||
} else {
|
||||
/* Ctrl-D is the same as "quit" */
|
||||
string_list_clear(&del_list, 0);
|
||||
putchar('\n');
|
||||
printf_ln("Bye.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (confirm.len) {
|
||||
if (!strncasecmp(confirm.buf, "yes", confirm.len)) {
|
||||
break;
|
||||
} else if (!strncasecmp(confirm.buf, "no", confirm.len) ||
|
||||
!strncasecmp(confirm.buf, "quit", confirm.len)) {
|
||||
string_list_clear(&del_list, 0);
|
||||
printf_ln("Bye.");
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strbuf_release(&buf);
|
||||
strbuf_release(&confirm);
|
||||
}
|
||||
|
||||
int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i, res;
|
||||
|
@ -162,6 +207,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
OPT__QUIET(&quiet, N_("do not print names of files removed")),
|
||||
OPT__DRY_RUN(&dry_run, N_("dry run")),
|
||||
OPT__FORCE(&force, N_("force")),
|
||||
OPT_BOOL('i', "interactive", &interactive, N_("interactive cleaning")),
|
||||
OPT_BOOLEAN('d', NULL, &remove_directories,
|
||||
N_("remove whole directories")),
|
||||
{ OPTION_CALLBACK, 'e', "exclude", &exclude_list, N_("pattern"),
|
||||
|
@ -188,12 +234,12 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
if (ignored && ignored_only)
|
||||
die(_("-x and -X cannot be used together"));
|
||||
|
||||
if (!dry_run && !force) {
|
||||
if (!interactive && !dry_run && !force) {
|
||||
if (config_set)
|
||||
die(_("clean.requireForce set to true and neither -n nor -f given; "
|
||||
die(_("clean.requireForce set to true and neither -i, -n nor -f given; "
|
||||
"refusing to clean"));
|
||||
else
|
||||
die(_("clean.requireForce defaults to true and neither -n nor -f given; "
|
||||
die(_("clean.requireForce defaults to true and neither -i, -n nor -f given; "
|
||||
"refusing to clean"));
|
||||
}
|
||||
|
||||
|
@ -267,7 +313,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: do interactive git-clean here, which will modify del_list */
|
||||
if (interactive && del_list.nr > 0)
|
||||
interactive_main_loop();
|
||||
|
||||
for_each_string_list_item(item, &del_list) {
|
||||
struct stat st;
|
||||
|
|
Загрузка…
Ссылка в новой задаче