Skip to content

Commit c298086

Browse files
committed
Merge branch 'jx/clean-interactive'
* jx/clean-interactive: git-clean: implement partial matching for selection Documentation/git-clean: fix description for range
2 parents 8dc84fd + 6083861 commit c298086

File tree

3 files changed

+91
-31
lines changed

3 files changed

+91
-31
lines changed

Documentation/git-clean.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ select by numbers::
111111
'>>' like this, you can make more than one selection, concatenated
112112
with whitespace or comma. Also you can say ranges. E.g. "2-5 7,9"
113113
to choose 2,3,4,5,7,9 from the list. If the second number in a
114-
range is omitted, all remaining patches are taken. E.g. "7-" to
114+
range is omitted, all remaining items are selected. E.g. "7-" to
115115
choose 7,8,9 from the list. You can say '*' to choose everything.
116116
Also when you are satisfied with the filtered result, press ENTER
117117
(empty) back to the main menu.

builtin/clean.c

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,56 @@ static void print_highlight_menu_stuff(struct menu_stuff *stuff, int **chosen)
365365
string_list_clear(&menu_list, 0);
366366
}
367367

368+
static int find_unique(const char *choice, struct menu_stuff *menu_stuff)
369+
{
370+
struct menu_item *menu_item;
371+
struct string_list_item *string_list_item;
372+
int i, len, found = 0;
373+
374+
len = strlen(choice);
375+
switch (menu_stuff->type) {
376+
default:
377+
die("Bad type of menu_stuff when parse choice");
378+
case MENU_STUFF_TYPE_MENU_ITEM:
379+
380+
menu_item = (struct menu_item *)menu_stuff->stuff;
381+
for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
382+
if (len == 1 && *choice == menu_item->hotkey) {
383+
found = i + 1;
384+
break;
385+
}
386+
if (!strncasecmp(choice, menu_item->title, len)) {
387+
if (found) {
388+
if (len == 1) {
389+
/* continue for hotkey matching */
390+
found = -1;
391+
} else {
392+
found = 0;
393+
break;
394+
}
395+
} else {
396+
found = i + 1;
397+
}
398+
}
399+
}
400+
break;
401+
case MENU_STUFF_TYPE_STRING_LIST:
402+
string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
403+
for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
404+
if (!strncasecmp(choice, string_list_item->string, len)) {
405+
if (found) {
406+
found = 0;
407+
break;
408+
}
409+
found = i + 1;
410+
}
411+
}
412+
break;
413+
}
414+
return found;
415+
}
416+
417+
368418
/*
369419
* Parse user input, and return choice(s) for menu (menu_stuff).
370420
*
@@ -392,8 +442,6 @@ static int parse_choice(struct menu_stuff *menu_stuff,
392442
int **chosen)
393443
{
394444
struct strbuf **choice_list, **ptr;
395-
struct menu_item *menu_item;
396-
struct string_list_item *string_list_item;
397445
int nr = 0;
398446
int i;
399447

@@ -457,32 +505,8 @@ static int parse_choice(struct menu_stuff *menu_stuff,
457505
bottom = 1;
458506
top = menu_stuff->nr;
459507
} else {
460-
switch (menu_stuff->type) {
461-
default:
462-
die("Bad type of menu_stuff when parse choice");
463-
case MENU_STUFF_TYPE_MENU_ITEM:
464-
menu_item = (struct menu_item *)menu_stuff->stuff;
465-
for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
466-
if (((*ptr)->len == 1 &&
467-
*(*ptr)->buf == menu_item->hotkey) ||
468-
!strcasecmp((*ptr)->buf, menu_item->title)) {
469-
bottom = i + 1;
470-
top = bottom;
471-
break;
472-
}
473-
}
474-
break;
475-
case MENU_STUFF_TYPE_STRING_LIST:
476-
string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
477-
for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
478-
if (!strcasecmp((*ptr)->buf, string_list_item->string)) {
479-
bottom = i + 1;
480-
top = bottom;
481-
break;
482-
}
483-
}
484-
break;
485-
}
508+
bottom = find_unique((*ptr)->buf, menu_stuff);
509+
top = bottom;
486510
}
487511

488512
if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top ||

t/t7301-clean-interactive.sh

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test_expect_success 'setup' '
1717
1818
'
1919

20-
test_expect_success 'git clean -i (clean)' '
20+
test_expect_success 'git clean -i (c: clean hotkey)' '
2121
2222
mkdir -p build docs &&
2323
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
@@ -38,12 +38,33 @@ test_expect_success 'git clean -i (clean)' '
3838
3939
'
4040

41+
test_expect_success 'git clean -i (cl: clean prefix)' '
42+
43+
mkdir -p build docs &&
44+
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
45+
docs/manual.txt obj.o build/lib.so &&
46+
echo cl | git clean -i &&
47+
test -f Makefile &&
48+
test -f README &&
49+
test -f src/part1.c &&
50+
test -f src/part2.c &&
51+
test ! -f a.out &&
52+
test -f docs/manual.txt &&
53+
test ! -f src/part3.c &&
54+
test ! -f src/part3.h &&
55+
test ! -f src/part4.c &&
56+
test ! -f src/part4.h &&
57+
test -f obj.o &&
58+
test -f build/lib.so
59+
60+
'
61+
4162
test_expect_success 'git clean -i (quit)' '
4263
4364
mkdir -p build docs &&
4465
touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
4566
docs/manual.txt obj.o build/lib.so &&
46-
echo q | git clean -i &&
67+
echo quit | git clean -i &&
4768
test -f Makefile &&
4869
test -f README &&
4970
test -f src/part1.c &&
@@ -256,6 +277,21 @@ test_expect_success 'git clean -id (select - number 3)' '
256277
257278
'
258279

280+
test_expect_success 'git clean -id (select - filenames)' '
281+
282+
mkdir -p build docs &&
283+
touch a.out foo.txt bar.txt baz.txt &&
284+
(echo s; echo a.out fo ba bar; echo; echo c) | \
285+
git clean -id &&
286+
test -f Makefile &&
287+
test ! -f a.out &&
288+
test ! -f foo.txt &&
289+
test ! -f bar.txt &&
290+
test -f baz.txt &&
291+
rm baz.txt
292+
293+
'
294+
259295
test_expect_success 'git clean -id (select - range)' '
260296
261297
mkdir -p build docs &&

0 commit comments

Comments
 (0)