I feel change the order of patch 01/15 and patch 02/15 is better.
I.E. Add test cases for relative_path first, then refactor
relative_path and fix the test cases.
Also fix wrong indent in t/7301.
Differences with gitster/jx/clean-interactive:
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 75fb54..5bf76 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -82,8 +82,8 @@ and type return, like this:
------------
*** Commands ***
- 1: clean 2: filter by pattern 3: select by numbers
- 4: ask each 5: quit 6: help
+ 1: clean 2: filter by pattern 3: select by numbers
+ 4: ask each 5: quit 6: help
What now> 1
------------
diff --git a/builtin/clean.c b/builtin/clean.c
index 73ba2..7d34b 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -64,7 +64,7 @@ struct menu_opts {
struct menu_item {
char hotkey;
- char *title;
+ const char *title;
int selected;
int (*fn)();
};
@@ -312,22 +312,26 @@ static void print_highlight_menu_stuff(struct menu_stuff
*stuff, int **chosen)
{
struct string_list menu_list = STRING_LIST_INIT_DUP;
struct strbuf menu = STRBUF_INIT;
+ struct strbuf buf = STRBUF_INIT;
+ struct menu_item *menu_item;
+ struct string_list_item *string_list_item;
int i;
- if (stuff->type == MENU_STUFF_TYPE_MENU_ITEM) {
- struct menu_item *item;
-
- item = (struct menu_item *)stuff->stuff;
- for (i = 0; i < stuff->nr; i++, item++) {
- char *p;
+ switch (stuff->type) {
+ default:
+ die("Bad type of menu_staff when print menu");
+ case MENU_STUFF_TYPE_MENU_ITEM:
+ menu_item = (struct menu_item *)stuff->stuff;
+ for (i = 0; i < stuff->nr; i++, menu_item++) {
+ const char *p;
int highlighted = 0;
- p = item->title;
+ p = menu_item->title;
if ((*chosen)[i] < 0)
- (*chosen)[i] = item->selected ? 1 : 0;
+ (*chosen)[i] = menu_item->selected ? 1 : 0;
strbuf_addf(&menu, "%s%2d: ", (*chosen)[i] ? "*" : " ",
i+1);
for (; *p; p++) {
- if (!highlighted && *p == item->hotkey) {
+ if (!highlighted && *p == menu_item->hotkey) {
strbuf_addstr(&menu,
clean_get_color(CLEAN_COLOR_PROMPT));
strbuf_addch(&menu, *p);
strbuf_addstr(&menu,
clean_get_color(CLEAN_COLOR_RESET));
@@ -339,27 +343,25 @@ static void print_highlight_menu_stuff(struct menu_stuff
*stuff, int **chosen)
string_list_append(&menu_list, menu.buf);
strbuf_reset(&menu);
}
-
- } else if (stuff->type == MENU_STUFF_TYPE_STRING_LIST) {
- struct string_list_item *item;
- struct strbuf buf = STRBUF_INIT;
+ break;
+ case MENU_STUFF_TYPE_STRING_LIST:
i = 0;
-
- for_each_string_list_item(item, (struct string_list
*)stuff->stuff) {
+ for_each_string_list_item(string_list_item, (struct string_list
*)stuff->stuff) {
if ((*chosen)[i] < 0)
(*chosen)[i] = 0;
strbuf_addf(&menu, "%s%2d: %s",
- (*chosen)[i] ? "*" : " ", i + 1,
item->string);
+ (*chosen)[i] ? "*" : " ", i+1,
string_list_item->string);
string_list_append(&menu_list, menu.buf);
strbuf_reset(&menu);
i++;
}
- strbuf_release(&buf);
+ break;
}
pretty_print_menus(&menu_list);
strbuf_release(&menu);
+ strbuf_release(&buf);
string_list_clear(&menu_list, 0);
}
@@ -390,6 +392,8 @@ 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;
@@ -454,30 +458,31 @@ static int parse_choice(struct menu_stuff *menu_stuff,
bottom = 1;
top = menu_stuff->nr;
} else {
- if (MENU_STUFF_TYPE_MENU_ITEM == menu_stuff->type) {
- struct menu_item *item;
-
- item = (struct menu_item *)menu_stuff->stuff;
- for (i = 0; i < menu_stuff->nr; i++, item++) {
+ 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 == item->hotkey) ||
- !strcasecmp((*ptr)->buf,
item->title)) {
+ *(*ptr)->buf == menu_item->hotkey)
||
+ !strcasecmp((*ptr)->buf,
menu_item->title)) {
bottom = i + 1;
top = bottom;
break;
}
}
- } else if (MENU_STUFF_TYPE_STRING_LIST ==
menu_stuff->type) {
- struct string_list_item *item;
-
- item = ((struct string_list
*)menu_stuff->stuff)->items;
- for (i = 0; i < menu_stuff->nr; i++, item++) {
- if (!strcasecmp((*ptr)->buf,
item->string)) {
+ 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;
}
}
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index d3b33..6acff4 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -46,11 +46,11 @@ static const char *tag_modified = "";
static const char *tag_skip_worktree = "";
static const char *tag_resolve_undo = "";
-static void write_name(const char* name)
+static void write_name(const char *name)
{
/* turn off prefix, if run with "--full-name" */
- write_name_quoted_relative(name, prefix_len > 0 ? prefix : NULL,
+ write_name_quoted_relative(name, prefix_len ? prefix : NULL,
stdout, line_terminator);
}
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 09a42..dfe47 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -12,6 +12,11 @@ norm_path() {
"test \"\$(test-path-utils normalize_path_copy '$1')\" = '$2'"
}
+relative_path() {
+ test_expect_success $4 "relative path: $1 $2 => $3" \
+ "test \"\$(test-path-utils relative_path '$1' '$2')\" = '$3'"
+}
+
# On Windows, we are using MSYS's bash, which mangles the paths.
# Absolute paths are anchored at the MSYS installation directory,
# which means that the path / accounts for this many characters:
@@ -183,4 +188,22 @@ test_expect_success SYMLINKS 'real path works on symlinks'
'
test "$sym" = "$(test-path-utils real_path "$dir2/syml")"
'
+relative_path /a/b/c/ /a/b/ c/
+relative_path /a/b/c/ /a/b c/
+relative_path /a//b//c/ //a/b// c/
+relative_path /a/b /a/b ./
+relative_path /a/b/ /a/b ./
+relative_path /a /a/b ../
+relative_path / /a/b/ ../../
+relative_path /a/c /a/b/ ../c
+relative_path /a/c /a/b ../c
+relative_path /a/b "<empty>" /a/b
+relative_path /a/b "<null>" /a/b
+relative_path "<empty>" /a/b ./
+relative_path "<empty>" "<empty>" ./
+relative_path "<empty>" "<null>" ./
+relative_path "<null>" "<empty>" ./
+relative_path "<null>" "<null>" ./
+relative_path "<null>" /a/b ./
+
test_done
diff --git a/test-path-utils.c b/test-path-utils.c
index 0092cb..bc4ad 100644
--- a/test-path-utils.c
+++ b/test-path-utils.c
@@ -1,6 +1,19 @@
#include "cache.h"
#include "string-list.h"
+#define PARSE_ARGV_STRING(var, input) do { \
+ if (!strcmp(input, "<null>")) { \
+ var = NULL; \
+ } else if (!strcmp(input, "<empty>")) { \
+ var = ""; \
+ } else if (*input == '<' || *input == '(') { \
+ fprintf(stderr, "Bad value: %s\n", input); \
+ return 1; \
+ } else { \
+ var = input; \
+ } \
+} while (0)
+
/*
* A "string_list_each_func_t" function that normalizes an entry from
* GIT_CEILING_DIRECTORIES. If the path is unusable for some reason,
@@ -103,6 +116,20 @@ int main(int argc, char **argv)
return 0;
}
+ if (argc == 4 && !strcmp(argv[1], "relative_path")) {
+ struct strbuf sb = STRBUF_INIT;
+ const char *abs, *base, *rel;
+ PARSE_ARGV_STRING(abs, argv[2]);
+ PARSE_ARGV_STRING(base, argv[3]);
+ rel = relative_path(abs, base, &sb);
+ if (!rel)
+ puts("(null)");
+ else
+ puts(strlen(rel) > 0 ? rel : "(empty)");
+ strbuf_release(&sb);
+ return 0;
+ }
+
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;
Jiang Xin (15):
test: add test cases for relative_path
path.c: refactor relative_path(), not only strip prefix
quote.c: remove path_relative, use relative_path instead
Refactor quote_path_relative, remove unused params
Refactor write_name_quoted_relative, remove unused params
git-clean: refactor git-clean into two phases
git-clean: add support for -i/--interactive
git-clean: show items of del_list in columns
git-clean: add colors to interactive git-clean
git-clean: use a git-add-interactive compatible UI
git-clean: add filter by pattern interactive action
git-clean: add select by numbers interactive action
git-clean: add ask each interactive action
git-clean: add documentation for interactive git-clean
test: add t7301 for git-clean--interactive
Documentation/config.txt | 21 +-
Documentation/git-clean.txt | 71 +++-
builtin/clean.c | 779 +++++++++++++++++++++++++++++++++++++++++--
builtin/grep.c | 5 +-
builtin/ls-files.c | 16 +-
cache.h | 2 +-
path.c | 112 +++++--
quote.c | 65 +---
quote.h | 7 +-
setup.c | 5 +-
t/t0060-path-utils.sh | 23 ++
t/t7301-clean-interactive.sh | 439 ++++++++++++++++++++++++
test-path-utils.c | 27 ++
wt-status.c | 17 +-
14 files changed, 1438 insertions(+), 151 deletions(-)
create mode 100755 t/t7301-clean-interactive.sh
--
1.8.3.rc2.26.g7472058
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html