Skip to content

Commit d123926

Browse files
jiangxingitster
authored andcommitted
git-clean: add filter by pattern interactive action
Add a new action for interactive git-clean: filter by pattern. When the user chooses this action, user can input space-separated patterns (the same syntax as gitignore), and each clean candidate that matches with one of the patterns will be excluded from cleaning. When the user feels it's OK, presses ENTER and backs to the confirmation dialog. Signed-off-by: Jiang Xin <[email protected]> Suggested-by: Junio C Hamano <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9f93e46 commit d123926

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

builtin/clean.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,72 @@ static int clean_cmd(void)
614614
return MENU_RETURN_NO_LOOP;
615615
}
616616

617+
static int filter_by_patterns_cmd(void)
618+
{
619+
struct dir_struct dir;
620+
struct strbuf confirm = STRBUF_INIT;
621+
struct strbuf **ignore_list;
622+
struct string_list_item *item;
623+
struct exclude_list *el;
624+
int changed = -1, i;
625+
626+
for (;;) {
627+
if (!del_list.nr)
628+
break;
629+
630+
if (changed)
631+
pretty_print_dels();
632+
633+
clean_print_color(CLEAN_COLOR_PROMPT);
634+
printf(_("Input ignore patterns>> "));
635+
clean_print_color(CLEAN_COLOR_RESET);
636+
if (strbuf_getline(&confirm, stdin, '\n') != EOF)
637+
strbuf_trim(&confirm);
638+
else
639+
putchar('\n');
640+
641+
/* quit filter_by_pattern mode if press ENTER or Ctrl-D */
642+
if (!confirm.len)
643+
break;
644+
645+
memset(&dir, 0, sizeof(dir));
646+
el = add_exclude_list(&dir, EXC_CMDL, "manual exclude");
647+
ignore_list = strbuf_split_max(&confirm, ' ', 0);
648+
649+
for (i = 0; ignore_list[i]; i++) {
650+
strbuf_trim(ignore_list[i]);
651+
if (!ignore_list[i]->len)
652+
continue;
653+
654+
add_exclude(ignore_list[i]->buf, "", 0, el, -(i+1));
655+
}
656+
657+
changed = 0;
658+
for_each_string_list_item(item, &del_list) {
659+
int dtype = DT_UNKNOWN;
660+
661+
if (is_excluded(&dir, item->string, &dtype)) {
662+
*item->string = '\0';
663+
changed++;
664+
}
665+
}
666+
667+
if (changed) {
668+
string_list_remove_empty_items(&del_list, 0);
669+
} else {
670+
clean_print_color(CLEAN_COLOR_ERROR);
671+
printf_ln(_("WARNING: Cannot find items matched by: %s"), confirm.buf);
672+
clean_print_color(CLEAN_COLOR_RESET);
673+
}
674+
675+
strbuf_list_free(ignore_list);
676+
clear_directory(&dir);
677+
}
678+
679+
strbuf_release(&confirm);
680+
return 0;
681+
}
682+
617683
static int quit_cmd(void)
618684
{
619685
string_list_clear(&del_list, 0);
@@ -626,6 +692,7 @@ static int help_cmd(void)
626692
clean_print_color(CLEAN_COLOR_HELP);
627693
printf_ln(_(
628694
"clean - start cleaning\n"
695+
"filter by pattern - exclude items from deletion\n"
629696
"quit - stop cleaning\n"
630697
"help - this screen\n"
631698
"? - help for prompt selection"
@@ -641,6 +708,7 @@ static void interactive_main_loop(void)
641708
struct menu_stuff menu_stuff;
642709
struct menu_item menus[] = {
643710
{'c', "clean", 0, clean_cmd},
711+
{'f', "filter by pattern", 0, filter_by_patterns_cmd},
644712
{'q', "quit", 0, quit_cmd},
645713
{'h', "help", 0, help_cmd},
646714
};

0 commit comments

Comments
 (0)