[PATCH] Fix support for old libcurl
[gitweb.git] / tree.c
diff --git a/tree.c b/tree.c
index d448daeab172a2a8b1a1c0624319f3f0096d40c0..8f490b8984bf95a13720ffb2d9b23a2dd8c03394 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -18,11 +18,56 @@ static int read_one_entry(unsigned char *sha1, const char *base, int baselen, co
        memcpy(ce->name, base, baselen);
        memcpy(ce->name + baselen, pathname, len+1);
        memcpy(ce->sha1, sha1, 20);
-       return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD);
+       return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
+}
+
+static int match_tree_entry(const char *base, int baselen, const char *path, unsigned int mode, const char **paths)
+{
+       const char *match;
+       int pathlen;
+
+       if (!paths)
+               return 1;
+       pathlen = strlen(path);
+       while ((match = *paths++) != NULL) {
+               int matchlen = strlen(match);
+
+               if (baselen >= matchlen) {
+                       /* If it doesn't match, move along... */
+                       if (strncmp(base, match, matchlen))
+                               continue;
+                       /* The base is a subdirectory of a path which was specified. */
+                       return 1;
+               }
+
+               /* Does the base match? */
+               if (strncmp(base, match, baselen))
+                       continue;
+
+               match += baselen;
+               matchlen -= baselen;
+
+               if (pathlen > matchlen)
+                       continue;
+
+               if (matchlen > pathlen) {
+                       if (match[pathlen] != '/')
+                               continue;
+                       if (!S_ISDIR(mode))
+                               continue;
+               }
+
+               if (strncmp(path, match, pathlen))
+                       continue;
+
+               return 1;
+       }
+       return 0;
 }
 
 static int read_tree_recursive(void *buffer, unsigned long size,
-                              const char *base, int baselen, int stage)
+                              const char *base, int baselen,
+                              int stage, const char **match)
 {
        while (size) {
                int len = strlen(buffer)+1;
@@ -36,6 +81,9 @@ static int read_tree_recursive(void *buffer, unsigned long size,
                buffer = sha1 + 20;
                size -= len + 20;
 
+               if (!match_tree_entry(base, baselen, path, mode, match))
+                       continue;
+
                if (S_ISDIR(mode)) {
                        int retval;
                        int pathlen = strlen(path);
@@ -55,7 +103,8 @@ static int read_tree_recursive(void *buffer, unsigned long size,
                        newbase[baselen + pathlen] = '/';
                        retval = read_tree_recursive(eltbuf, eltsize,
                                                     newbase,
-                                                    baselen + pathlen + 1, stage);
+                                                    baselen + pathlen + 1,
+                                                    stage, match);
                        free(eltbuf);
                        free(newbase);
                        if (retval)
@@ -68,12 +117,12 @@ static int read_tree_recursive(void *buffer, unsigned long size,
        return 0;
 }
 
-int read_tree(void *buffer, unsigned long size, int stage)
+int read_tree(void *buffer, unsigned long size, int stage, const char **match)
 {
-       return read_tree_recursive(buffer, size, "", 0, stage);
+       return read_tree_recursive(buffer, size, "", 0, stage, match);
 }
 
-struct tree *lookup_tree(unsigned char *sha1)
+struct tree *lookup_tree(const unsigned char *sha1)
 {
        struct object *obj = lookup_object(sha1);
        if (!obj) {
@@ -118,6 +167,7 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
                entry->directory = S_ISDIR(mode) != 0;
                entry->executable = (mode & S_IXUSR) != 0;
                entry->symlink = S_ISLNK(mode) != 0;
+               entry->zeropad = *(char *)bufptr == '0';
                entry->mode = mode;
                entry->next = NULL;
 
@@ -133,7 +183,7 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
                }
                if (obj)
                        add_ref(&item->object, obj);
-
+               entry->parent = NULL; /* needs to be filled by the user */
                *list_p = entry;
                list_p = &entry->next;
        }