Add new wrapper `scan_clean_candidates`, which determines the del_list
(i.e. the cleaning candidates). This function will be reused later in
the interactive git-clean, so we can change flags of git-clean and
refresh the del_list.

Signed-off-by: Jiang Xin <worldhello....@gmail.com>
---
 builtin/clean.c | 169 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 93 insertions(+), 76 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 26d00..232d48 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -295,6 +295,96 @@ static const char *path_relative(const char *in, const 
char *prefix)
        return buf;
 }
 
+static void scan_clean_candidates(const char **pathspec,
+                                 struct string_list exclude_list,
+                                 const char *prefix)
+{
+       struct dir_struct dir;
+       struct exclude_list *el;
+       char *seen = NULL;
+       const char **pathspec_p = pathspec;
+       const char *rel;
+       int pathspec_nr = 0;
+       int i;
+
+       while (pathspec_p && *(pathspec_p++))
+               pathspec_nr++;
+
+       memset(&dir, 0, sizeof(dir));
+       if (clean_flags & CLEAN_OPTS_IGNORED_ONLY)
+               dir.flags |= DIR_SHOW_IGNORED;
+
+       if (clean_flags & CLEAN_OPTS_IGNORED_ONLY &&
+           clean_flags & CLEAN_OPTS_SHOW_IGNORED)
+               die(_("-x and -X cannot be used together"));
+
+       dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
+
+       if (!(clean_flags & CLEAN_OPTS_SHOW_IGNORED))
+               setup_standard_excludes(&dir);
+
+       el = add_exclude_list(&dir, EXC_CMDL, "--exclude option");
+       for (i = 0; i < exclude_list.nr; i++)
+               add_exclude(exclude_list.items[i].string, "", 0, el, -(i+1));
+
+       fill_directory(&dir, pathspec);
+
+       if (pathspec)
+               seen = xmalloc(pathspec_nr > 0 ? pathspec_nr : 1);
+
+       string_list_clear(&del_list, 0);
+
+       for (i = 0; i < dir.nr; i++) {
+               struct dir_entry *ent = dir.entries[i];
+               int len, pos;
+               int matches = 0;
+               struct cache_entry *ce;
+               struct stat st;
+
+               /*
+                * Remove the '/' at the end that directory
+                * walking adds for directory entries.
+                */
+               len = ent->len;
+               if (len && ent->name[len-1] == '/')
+                       len--;
+               pos = cache_name_pos(ent->name, len);
+               if (0 <= pos)
+                       continue;       /* exact match */
+               pos = -pos - 1;
+               if (pos < active_nr) {
+                       ce = active_cache[pos];
+                       if (ce_namelen(ce) == len &&
+                           !memcmp(ce->name, ent->name, len))
+                               continue; /* Yup, this one exists unmerged */
+               }
+
+               if (lstat(ent->name, &st))
+                       continue;
+
+               if (pathspec) {
+                       memset(seen, 0, pathspec_nr > 0 ? pathspec_nr : 1);
+                       matches = match_pathspec(pathspec, ent->name, len,
+                                                0, seen);
+               }
+
+               if (S_ISDIR(st.st_mode)) {
+                       if ((clean_flags & CLEAN_OPTS_REMOVE_DIRECTORIES) ||
+                           (matches == MATCHED_EXACTLY)) {
+                               rel = path_relative(ent->name, prefix);
+                               string_list_append(&del_list, rel);
+                       }
+               } else {
+                       if (pathspec && !matches)
+                               continue;
+                       rel = path_relative(ent->name, prefix);
+                       string_list_append(&del_list, rel);
+               }
+       }
+
+       free(seen);
+}
+
 static void pretty_print_dels(void)
 {
        struct string_list list = STRING_LIST_INIT_DUP;
@@ -871,18 +961,15 @@ static void interactive_main_loop(void)
 
 int cmd_clean(int argc, const char **argv, const char *prefix)
 {
-       int i, res;
+       int res;
        int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0;
        int ignored_only = 0, config_set = 0, errors = 0, gone = 1;
        struct strbuf abs_path = STRBUF_INIT;
-       struct dir_struct dir;
        static const char **pathspec;
        struct strbuf buf = STRBUF_INIT;
-       struct string_list exclude_list = STRING_LIST_INIT_NODUP;
-       struct exclude_list *el;
        struct string_list_item *item;
+       struct string_list exclude_list = STRING_LIST_INIT_NODUP;
        const char *qname;
-       char *seen = NULL;
        struct option options[] = {
                OPT__QUIET(&quiet, N_("do not print names of files removed")),
                OPT__DRY_RUN(&dry_run, N_("dry run")),
@@ -932,78 +1019,9 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
        if (remove_directories)
                clean_flags |= CLEAN_OPTS_REMOVE_DIRECTORIES;
 
-       memset(&dir, 0, sizeof(dir));
-       if (clean_flags & CLEAN_OPTS_IGNORED_ONLY)
-               dir.flags |= DIR_SHOW_IGNORED;
-
-       if (clean_flags & CLEAN_OPTS_IGNORED_ONLY &&
-           clean_flags & CLEAN_OPTS_SHOW_IGNORED)
-               die(_("-x and -X cannot be used together"));
-
-       dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
-
-       if (!(clean_flags & CLEAN_OPTS_SHOW_IGNORED))
-               setup_standard_excludes(&dir);
-
-       el = add_exclude_list(&dir, EXC_CMDL, "--exclude option");
-       for (i = 0; i < exclude_list.nr; i++)
-               add_exclude(exclude_list.items[i].string, "", 0, el, -(i+1));
-
        pathspec = get_pathspec(prefix, argv);
 
-       fill_directory(&dir, pathspec);
-
-       if (pathspec)
-               seen = xmalloc(argc > 0 ? argc : 1);
-
-       for (i = 0; i < dir.nr; i++) {
-               struct dir_entry *ent = dir.entries[i];
-               int len, pos;
-               int matches = 0;
-               struct cache_entry *ce;
-               struct stat st;
-               const char *rel;
-
-               /*
-                * Remove the '/' at the end that directory
-                * walking adds for directory entries.
-                */
-               len = ent->len;
-               if (len && ent->name[len-1] == '/')
-                       len--;
-               pos = cache_name_pos(ent->name, len);
-               if (0 <= pos)
-                       continue;       /* exact match */
-               pos = -pos - 1;
-               if (pos < active_nr) {
-                       ce = active_cache[pos];
-                       if (ce_namelen(ce) == len &&
-                           !memcmp(ce->name, ent->name, len))
-                               continue; /* Yup, this one exists unmerged */
-               }
-
-               if (lstat(ent->name, &st))
-                       continue;
-
-               if (pathspec) {
-                       memset(seen, 0, argc > 0 ? argc : 1);
-                       matches = match_pathspec(pathspec, ent->name, len,
-                                                0, seen);
-               }
-
-               if (S_ISDIR(st.st_mode)) {
-                       if ((clean_flags & CLEAN_OPTS_REMOVE_DIRECTORIES) ||
-                           (matches == MATCHED_EXACTLY)) {
-                               rel = path_relative(ent->name, prefix);
-                               string_list_append(&del_list, rel);
-                       }
-               } else {
-                       if (pathspec && !matches)
-                               continue;
-                       rel = path_relative(ent->name, prefix);
-                       string_list_append(&del_list, rel);
-               }
-       }
+       scan_clean_candidates(pathspec, exclude_list, prefix);
 
        if (interactive && !dry_run && del_list.nr > 0)
                interactive_main_loop();
@@ -1047,7 +1065,6 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
                }
                strbuf_reset(&abs_path);
        }
-       free(seen);
 
        strbuf_release(&abs_path);
        string_list_clear(&del_list, 0);
-- 
1.8.3.rc1.341.g24a8a0f

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to