Merge branch 'nd/struct-pathspec'
authorJunio C Hamano <gitster@pobox.com>
Mon, 28 Feb 2011 05:17:36 +0000 (21:17 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 28 Feb 2011 05:17:36 +0000 (21:17 -0800)
* nd/struct-pathspec: (22 commits)
t6004: add pathspec globbing test for log family
t7810: overlapping pathspecs and depth limit
grep: drop pathspec_matches() in favor of tree_entry_interesting()
grep: use writable strbuf from caller for grep_tree()
grep: use match_pathspec_depth() for cache/worktree grepping
grep: convert to use struct pathspec
Convert ce_path_match() to use match_pathspec_depth()
Convert ce_path_match() to use struct pathspec
struct rev_info: convert prune_data to struct pathspec
pathspec: add match_pathspec_depth()
tree_entry_interesting(): optimize wildcard matching when base is matched
tree_entry_interesting(): support wildcard matching
tree_entry_interesting(): fix depth limit with overlapping pathspecs
tree_entry_interesting(): support depth limit
tree_entry_interesting(): refactor into separate smaller functions
diff-tree: convert base+baselen to writable strbuf
glossary: define pathspec
Move tree_entry_interesting() to tree-walk.c and export it
tree_entry_interesting(): remove dependency on struct diff_options
Convert struct diff_options to use struct pathspec
...

1  2 
builtin/add.c
builtin/diff.c
cache.h
read-cache.c
diff --combined builtin/add.c
index 5c9f4afef21908f3d5814ad0f9e6f2b5ff55b0b8,5f817ad77f1b3ba247c3b76d1d9a50f7fcc5edee..f7a17e43f6816622ab4ff836a169221289756505
@@@ -86,7 -86,7 +86,7 @@@ int add_files_to_cache(const char *pref
        struct rev_info rev;
        init_revisions(&rev, prefix);
        setup_revisions(0, NULL, &rev, NULL);
-       rev.prune_data = pathspec;
+       init_pathspec(&rev.prune_data, pathspec);
        rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = update_callback;
        data.flags = flags;
@@@ -317,12 -317,12 +317,12 @@@ static struct option builtin_add_option
        OPT__VERBOSE(&verbose, "be verbose"),
        OPT_GROUP(""),
        OPT_BOOLEAN('i', "interactive", &add_interactive, "interactive picking"),
 -      OPT_BOOLEAN('p', "patch", &patch_interactive, "interactive patching"),
 +      OPT_BOOLEAN('p', "patch", &patch_interactive, "select hunks interactively"),
        OPT_BOOLEAN('e', "edit", &edit_interactive, "edit current diff and apply"),
        OPT__FORCE(&ignored_too, "allow adding otherwise ignored files"),
        OPT_BOOLEAN('u', "update", &take_worktree_changes, "update tracked files"),
        OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, "record only the fact that the path will be added later"),
 -      OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"),
 +      OPT_BOOLEAN('A', "all", &addremove, "add changes from all tracked and untracked files"),
        OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
        OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
        OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, "check if - even missing - files are ignored in dry run"),
diff --combined builtin/diff.c
index 42822cd5374dbcf0e63c17078a55284c432ddc77,d12de8f392fc660c5048062f2a754a9f63e897fb..4c9deb28ec15d0c2adae795cc2c177b24256e585
@@@ -135,7 -135,7 +135,7 @@@ static int builtin_diff_index(struct re
            revs->max_count != -1 || revs->min_age != -1 ||
            revs->max_age != -1)
                usage(builtin_diff_usage);
-       if (read_cache_preload(revs->diffopt.paths) < 0) {
+       if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
                perror("read_cache_preload");
                return -1;
        }
@@@ -237,7 -237,7 +237,7 @@@ static int builtin_diff_files(struct re
                revs->combine_merges = revs->dense_combined_merges = 1;
  
        setup_work_tree();
-       if (read_cache_preload(revs->diffopt.paths) < 0) {
+       if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
                perror("read_cache_preload");
                return -1;
        }
@@@ -330,11 -330,8 +330,11 @@@ int cmd_diff(int argc, const char **arg
                        else if (!strcmp(arg, "--cached") ||
                                 !strcmp(arg, "--staged")) {
                                add_head_to_pending(&rev);
 -                              if (!rev.pending.nr)
 -                                      die("No HEAD commit to compare with (yet)");
 +                              if (!rev.pending.nr) {
 +                                      struct tree *tree;
 +                                      tree = lookup_tree((const unsigned char*)EMPTY_TREE_SHA1_BIN);
 +                                      add_pending_object(&rev, &tree->object, "HEAD");
 +                              }
                                break;
                        }
                }
                }
                die("unhandled object '%s' given.", name);
        }
-       if (rev.prune_data) {
-               const char **pathspec = rev.prune_data;
-               while (*pathspec) {
-                       if (!path)
-                               path = *pathspec;
-                       paths++;
-                       pathspec++;
-               }
+       if (rev.prune_data.nr) {
+               if (!path)
+                       path = rev.prune_data.items[0].match;
+               paths += rev.prune_data.nr;
        }
  
        /*
diff --combined cache.h
index 4a758babec4b53bf8b98572128c5bbf11019beb3,4beb2dc6ff875322f970eccbf3980746527a91ab..677994a23a71d17ccaff7c5e461e96ec501742b8
+++ b/cache.h
@@@ -500,7 -500,22 +500,22 @@@ extern int index_name_is_other(const st
  extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
  extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
  
- extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
+ struct pathspec {
+       const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
+       int nr;
+       int has_wildcard:1;
+       int recursive:1;
+       int max_depth;
+       struct pathspec_item {
+               const char *match;
+               int len;
+               int has_wildcard:1;
+       } *items;
+ };
+ extern int init_pathspec(struct pathspec *, const char **);
+ extern void free_pathspec(struct pathspec *);
+ extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
  extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
  extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
  extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
  #define REFRESH_IGNORE_MISSING        0x0008  /* ignore non-existent */
  #define REFRESH_IGNORE_SUBMODULES     0x0010  /* ignore submodules */
  #define REFRESH_IN_PORCELAIN  0x0020  /* user friendly output, not "needs update" */
 -extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, char *header_msg);
 +extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, const char *header_msg);
  
  struct lock_file {
        struct lock_file *next;
@@@ -676,11 -691,9 +691,11 @@@ static inline void hashclr(unsigned cha
  
  #define EMPTY_TREE_SHA1_HEX \
        "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
 -#define EMPTY_TREE_SHA1_BIN \
 +#define EMPTY_TREE_SHA1_BIN_LITERAL \
         "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
         "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
 +#define EMPTY_TREE_SHA1_BIN \
 +       ((const unsigned char *) EMPTY_TREE_SHA1_BIN_LITERAL)
  
  int git_mkstemp(char *path, size_t n, const char *template);
  
diff --combined read-cache.c
index 15b0a73b6280b11dae91b2a1250ebdfb8a6c458f,7772079ad3101a2a51cfef1c5b1c250ed3ff37de..b97b5668ebc486561686d3e80b536e115dede513
@@@ -706,30 -706,9 +706,9 @@@ int ce_same_name(struct cache_entry *a
        return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
  }
  
- int ce_path_match(const struct cache_entry *ce, const char **pathspec)
+ int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec)
  {
-       const char *match, *name;
-       int len;
-       if (!pathspec)
-               return 1;
-       len = ce_namelen(ce);
-       name = ce->name;
-       while ((match = *pathspec++) != NULL) {
-               int matchlen = strlen(match);
-               if (matchlen > len)
-                       continue;
-               if (memcmp(name, match, matchlen))
-                       continue;
-               if (matchlen && name[matchlen-1] == '/')
-                       return 1;
-               if (name[matchlen] == '/' || !name[matchlen])
-                       return 1;
-               if (!matchlen)
-                       return 1;
-       }
-       return 0;
+       return match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL);
  }
  
  /*
@@@ -1104,7 -1083,7 +1083,7 @@@ static struct cache_entry *refresh_cach
  }
  
  static void show_file(const char * fmt, const char * name, int in_porcelain,
 -                    int * first, char *header_msg)
 +                    int * first, const char *header_msg)
  {
        if (in_porcelain && *first && header_msg) {
                printf("%s\n", header_msg);
  }
  
  int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec,
 -                char *seen, char *header_msg)
 +                char *seen, const char *header_msg)
  {
        int i;
        int has_errors = 0;