Merge branch 'jk/clean-d-pathspec'
authorJunio C Hamano <gitster@pobox.com>
Tue, 18 Mar 2014 20:47:57 +0000 (13:47 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Mar 2014 20:47:57 +0000 (13:47 -0700)
"git clean -d pathspec" did not use the given pathspec correctly
and ended up cleaning too much.

* jk/clean-d-pathspec:
clean: simplify dir/not-dir logic
clean: respect pathspecs with "-d"

1  2 
builtin/clean.c
diff --combined builtin/clean.c
index 114d7bf879690fb1c1c33f768b86776b6ff60ef8,4ec4fe2577dedb9e5895d3208a12248b6b82daf8..cf76b1f412e5423df42528c928c557764f31ad02
@@@ -100,7 -100,7 +100,7 @@@ static int parse_clean_color_slot(cons
  
  static int git_clean_config(const char *var, const char *value, void *cb)
  {
 -      if (!prefixcmp(var, "column."))
 +      if (starts_with(var, "column."))
                return git_column_config(var, value, "clean", &colopts);
  
        /* honors the color.interactive* config variables which also
                clean_use_color = git_config_colorbool(var, value);
                return 0;
        }
 -      if (!prefixcmp(var, "color.interactive.")) {
 +      if (starts_with(var, "color.interactive.")) {
                int slot = parse_clean_color_slot(var +
                                                  strlen("color.interactive."));
                if (slot < 0)
@@@ -154,7 -154,7 +154,7 @@@ static int remove_dirs(struct strbuf *p
        DIR *dir;
        struct strbuf quoted = STRBUF_INIT;
        struct dirent *e;
 -      int res = 0, ret = 0, gone = 1, original_len = path->len, len, i;
 +      int res = 0, ret = 0, gone = 1, original_len = path->len, len;
        unsigned char submodule_head[20];
        struct string_list dels = STRING_LIST_INIT_DUP;
  
        }
  
        if (!*dir_gone && !quiet) {
 +              int i;
                for (i = 0; i < dels.nr; i++)
                        printf(dry_run ?  _(msg_would_remove) : _(msg_remove), dels.items[i].string);
        }
@@@ -934,30 -933,46 +934,28 @@@ int cmd_clean(int argc, const char **ar
  
        for (i = 0; i < dir.nr; i++) {
                struct dir_entry *ent = dir.entries[i];
 -              int len, pos;
                int matches = 0;
 -              const 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 (!cache_name_is_other(ent->name, ent->len))
 +                      continue;
  
                if (lstat(ent->name, &st))
                        die_errno("Cannot lstat '%s'", ent->name);
  
                if (pathspec.nr)
 -                      matches = match_pathspec_depth(&pathspec, ent->name,
 -                                                     len, 0, NULL);
 +                      matches = dir_path_match(ent, &pathspec, 0, NULL);
  
-               if (S_ISDIR(st.st_mode)) {
-                       if (remove_directories || (matches == MATCHED_EXACTLY)) {
-                               rel = relative_path(ent->name, prefix, &buf);
-                               string_list_append(&del_list, rel);
-                       }
-               } else {
-                       if (pathspec.nr && !matches)
-                               continue;
-                       rel = relative_path(ent->name, prefix, &buf);
-                       string_list_append(&del_list, rel);
-               }
+               if (pathspec.nr && !matches)
+                       continue;
+               if (S_ISDIR(st.st_mode) && !remove_directories &&
+                   matches != MATCHED_EXACTLY)
+                       continue;
+               rel = relative_path(ent->name, prefix, &buf);
+               string_list_append(&del_list, rel);
        }
  
        if (interactive && del_list.nr > 0)