Add new action in the interactive mode, so that the user can change git-clean flags, such as -x/-X/-d/-ff, and refresh the cleaning candidates list. Signed-off-by: Jiang Xin <worldhello.net@xxxxxxxxx> --- Documentation/git-clean.txt | 11 +++-- builtin/clean.c | 117 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 108 insertions(+), 20 deletions(-) diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt index 47e8e..c7885 100644 --- a/Documentation/git-clean.txt +++ b/Documentation/git-clean.txt @@ -82,14 +82,14 @@ and type return, like this: ------------ *** Commands *** - 1: clean 2: edit by patterns 3: edit by numbers - 4. rm -i 5. quit 6. help + 1: clean 2: edit by patterns 3: edit by numbers 4: rm -i + 5: flags: none 6: quit 7: help What now> 2 ------------ You also could say `c` or `clean` above as long as the choice is unique. -The main command loop has 6 subcommands. +The main command loop has 7 subcommands. clean:: @@ -122,6 +122,11 @@ rm -i:: by one in order to delete items. This action is not as efficient as the above two actions. +flags:: + + This lets you change the flags for git-clean, such as -x/-X/-d/-ff, + and refresh the cleaning candidates list automatically. + quit:: This lets you quit without do cleaning. diff --git a/builtin/clean.c b/builtin/clean.c index 0d8561..b2941 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -850,6 +850,66 @@ static int rm_i_cmd() return MENU_RETURN_NO_LOOP; } +static int flags_cmd() +{ + struct menu_opts menu_opts; + struct menu_stuff menu_stuff; + struct menu_item menus[] = { + {'d', "(-d) remove directories", + clean_flags & CLEAN_OPTS_REMOVE_DIRECTORIES, NULL}, + {'x', "(-x) show ignored", + clean_flags & CLEAN_OPTS_SHOW_IGNORED, NULL}, + {'X', "(-X) ignored only", + clean_flags & CLEAN_OPTS_IGNORED_ONLY, NULL}, + {'f', "(-ff) remove nested.git", + clean_flags & CLEAN_OPTS_REMOVE_NESTED_GIT, NULL}, + }; + int new_flags = 0; + int *chosen; + int i; + + menu_opts.header = NULL; + menu_opts.prompt = "Change flags"; + menu_opts.flag = 0; + + menu_stuff.type = MENU_STUFF_TYPE_MENU_ITEM; + menu_stuff.stuff = menus; + menu_stuff.nr = sizeof(menus) / sizeof(struct menu_item); + + chosen = list_and_choose(&menu_opts, &menu_stuff); + + for (i = 0; chosen[i] != EOF; i++) { + switch (chosen[i]) { + case 0: + new_flags |= CLEAN_OPTS_REMOVE_DIRECTORIES; + break; + case 1: + new_flags |= CLEAN_OPTS_SHOW_IGNORED; + break; + case 2: + new_flags |= CLEAN_OPTS_IGNORED_ONLY; + break; + case 3: + new_flags |= CLEAN_OPTS_REMOVE_NESTED_GIT; + break; + default: + break; + } + } + + if (new_flags & CLEAN_OPTS_IGNORED_ONLY && + new_flags & CLEAN_OPTS_SHOW_IGNORED) { + clean_print_color(CLEAN_COLOR_ERROR); + printf_ln(_("-x and -X cannot be used together")); + clean_print_color(CLEAN_COLOR_RESET); + } else { + clean_flags = new_flags; + } + + free(chosen); + return 0; +} + static int quit_cmd() { string_list_clear(&del_list, 0); @@ -865,6 +925,7 @@ static int help_cmd(int x) "edit by patterns - exclude items from deletion\n" "edit by numbers - select items to be deleted by numbers\n" "rm -i - delete items one by one, like \"rm -i\"\n" + "flags - change git-clean flags and update the cleaning candidates\n" "quit - stop cleaning\n" "help - this screen\n" "? - help for prompt selection" @@ -873,10 +934,13 @@ static int help_cmd(int x) return 0; } -static void interactive_main_loop() +static void interactive_main_loop(const char **pathspec, struct string_list exclude_list) { + int cached_clean_flags = clean_flags; + char flags_title[20]; + /* dels list may become empty after return back from edit mode */ - while (del_list.nr) { + while (1) { struct menu_opts menu_opts; struct menu_stuff menu_stuff; struct menu_item menus[] = { @@ -884,11 +948,24 @@ static void interactive_main_loop() {'p', "edit by patterns", 0, edit_by_patterns_cmd}, {'n', "edit by numbers", 0, edit_by_numbers_cmd}, {'i', "rm -i", 0, rm_i_cmd}, + {'f', flags_title, 0, flags_cmd}, {'q', "quit", 0, quit_cmd}, {'h', "help", 0, help_cmd}, }; int *chosen; + if (!clean_flags) { + strncpy(flags_title, "flags: none", sizeof(flags_title)/sizeof(char)); + } else { + snprintf(flags_title, sizeof(flags_title)/sizeof(char), + "flags: -%s%s%s%s", + clean_flags & CLEAN_OPTS_REMOVE_DIRECTORIES ? "d" : "", + clean_flags & CLEAN_OPTS_SHOW_IGNORED ? "x" : "", + clean_flags & CLEAN_OPTS_IGNORED_ONLY ? "X" : "", + clean_flags & CLEAN_OPTS_REMOVE_NESTED_GIT ? "ff" : "" + ); + } + menu_opts.header = _("*** Commands ***"); menu_opts.prompt = "What now"; menu_opts.flag = MENU_OPTS_SINGLETON; @@ -897,14 +974,26 @@ static void interactive_main_loop() menu_stuff.stuff = menus; menu_stuff.nr = sizeof(menus) / sizeof(struct menu_item); - clean_print_color(CLEAN_COLOR_HEADER); - printf_ln(Q_("Would remove the following item:", - "Would remove the following items:", - del_list.nr)); - clean_print_color(CLEAN_COLOR_RESET); + if (cached_clean_flags != clean_flags) { + scan_clean_candidates(pathspec, exclude_list); + cached_clean_flags = clean_flags; + } - /* display dels in columns */ - pretty_print_dels(); + if (del_list.nr) { + clean_print_color(CLEAN_COLOR_HEADER); + printf_ln(Q_("Would remove the following item:", + "Would remove the following items:", + del_list.nr)); + clean_print_color(CLEAN_COLOR_RESET); + + /* display dels in columns */ + pretty_print_dels(); + } else { + clean_print_color(CLEAN_COLOR_HEADER); + printf_ln(_("NOTE: No more files to clean. Press \"f\" can change the flags.")); + putchar('\n'); + clean_print_color(CLEAN_COLOR_RESET); + } /* main menu */ chosen = list_and_choose(&menu_opts, &menu_stuff); @@ -915,12 +1004,6 @@ static void interactive_main_loop() if (ret != MENU_RETURN_NO_LOOP) { free(chosen); chosen = NULL; - if (!del_list.nr) { - clean_print_color(CLEAN_COLOR_ERROR); - printf_ln(_("No more files to clean, exiting.")); - clean_print_color(CLEAN_COLOR_RESET); - break; - } continue; } } else { @@ -999,8 +1082,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix) scan_clean_candidates(pathspec, exclude_list); - if (interactive && !dry_run && del_list.nr > 0) - interactive_main_loop(); + if (interactive && !dry_run) + interactive_main_loop(pathspec, exclude_list); for_each_string_list_item(item, &del_list) { struct stat st; -- 1.8.3.rc1.341.g1c24ab7 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html