Skip to content

Commit

Permalink
Merge branch 'jx/clean-interactive'
Browse files Browse the repository at this point in the history
* jx/clean-interactive:
  git-clean: implement partial matching for selection
  Documentation/git-clean: fix description for range
  • Loading branch information
Junio C Hamano committed Aug 1, 2013
2 parents 8dc84fd + 6083861 commit c298086
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Documentation/git-clean.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ select by numbers::
'>>' like this, you can make more than one selection, concatenated
with whitespace or comma. Also you can say ranges. E.g. "2-5 7,9"
to choose 2,3,4,5,7,9 from the list. If the second number in a
range is omitted, all remaining patches are taken. E.g. "7-" to
range is omitted, all remaining items are selected. E.g. "7-" to
choose 7,8,9 from the list. You can say '*' to choose everything.
Also when you are satisfied with the filtered result, press ENTER
(empty) back to the main menu.
Expand Down
80 changes: 52 additions & 28 deletions builtin/clean.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,56 @@ static void print_highlight_menu_stuff(struct menu_stuff *stuff, int **chosen)
string_list_clear(&menu_list, 0);
}

static int find_unique(const char *choice, struct menu_stuff *menu_stuff)
{
struct menu_item *menu_item;
struct string_list_item *string_list_item;
int i, len, found = 0;

len = strlen(choice);
switch (menu_stuff->type) {
default:
die("Bad type of menu_stuff when parse choice");
case MENU_STUFF_TYPE_MENU_ITEM:

menu_item = (struct menu_item *)menu_stuff->stuff;
for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
if (len == 1 && *choice == menu_item->hotkey) {
found = i + 1;
break;
}
if (!strncasecmp(choice, menu_item->title, len)) {
if (found) {
if (len == 1) {
/* continue for hotkey matching */
found = -1;
} else {
found = 0;
break;
}
} else {
found = i + 1;
}
}
}
break;
case MENU_STUFF_TYPE_STRING_LIST:
string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
if (!strncasecmp(choice, string_list_item->string, len)) {
if (found) {
found = 0;
break;
}
found = i + 1;
}
}
break;
}
return found;
}


/*
* Parse user input, and return choice(s) for menu (menu_stuff).
*
Expand Down Expand Up @@ -392,8 +442,6 @@ static int parse_choice(struct menu_stuff *menu_stuff,
int **chosen)
{
struct strbuf **choice_list, **ptr;
struct menu_item *menu_item;
struct string_list_item *string_list_item;
int nr = 0;
int i;

Expand Down Expand Up @@ -457,32 +505,8 @@ static int parse_choice(struct menu_stuff *menu_stuff,
bottom = 1;
top = menu_stuff->nr;
} else {
switch (menu_stuff->type) {
default:
die("Bad type of menu_stuff when parse choice");
case MENU_STUFF_TYPE_MENU_ITEM:
menu_item = (struct menu_item *)menu_stuff->stuff;
for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
if (((*ptr)->len == 1 &&
*(*ptr)->buf == menu_item->hotkey) ||
!strcasecmp((*ptr)->buf, menu_item->title)) {
bottom = i + 1;
top = bottom;
break;
}
}
break;
case MENU_STUFF_TYPE_STRING_LIST:
string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
if (!strcasecmp((*ptr)->buf, string_list_item->string)) {
bottom = i + 1;
top = bottom;
break;
}
}
break;
}
bottom = find_unique((*ptr)->buf, menu_stuff);
top = bottom;
}

if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top ||
Expand Down
40 changes: 38 additions & 2 deletions t/t7301-clean-interactive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ test_expect_success 'setup' '
'

test_expect_success 'git clean -i (clean)' '
test_expect_success 'git clean -i (c: clean hotkey)' '
mkdir -p build docs &&
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
Expand All @@ -38,12 +38,33 @@ test_expect_success 'git clean -i (clean)' '
'

test_expect_success 'git clean -i (cl: clean prefix)' '
mkdir -p build docs &&
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
docs/manual.txt obj.o build/lib.so &&
echo cl | git clean -i &&
test -f Makefile &&
test -f README &&
test -f src/part1.c &&
test -f src/part2.c &&
test ! -f a.out &&
test -f docs/manual.txt &&
test ! -f src/part3.c &&
test ! -f src/part3.h &&
test ! -f src/part4.c &&
test ! -f src/part4.h &&
test -f obj.o &&
test -f build/lib.so
'

test_expect_success 'git clean -i (quit)' '
mkdir -p build docs &&
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
docs/manual.txt obj.o build/lib.so &&
echo q | git clean -i &&
echo quit | git clean -i &&
test -f Makefile &&
test -f README &&
test -f src/part1.c &&
Expand Down Expand Up @@ -256,6 +277,21 @@ test_expect_success 'git clean -id (select - number 3)' '
'

test_expect_success 'git clean -id (select - filenames)' '
mkdir -p build docs &&
touch a.out foo.txt bar.txt baz.txt &&
(echo s; echo a.out fo ba bar; echo; echo c) | \
git clean -id &&
test -f Makefile &&
test ! -f a.out &&
test ! -f foo.txt &&
test ! -f bar.txt &&
test -f baz.txt &&
rm baz.txt
'

test_expect_success 'git clean -id (select - range)' '
mkdir -p build docs &&
Expand Down

0 comments on commit c298086

Please sign in to comment.