GIT 1.4.3-rc1
[gitweb.git] / cache-tree.c
index 28b78f88effe9ea766ff780fc948592c5fab51bf..323c68a6709f30312e0dfb0fd60fcd7e69cd710b 100644 (file)
@@ -110,6 +110,10 @@ void cache_tree_invalidate_path(struct cache_tree *it, const char *path)
        int namelen;
        struct cache_tree_sub *down;
 
+#if DEBUG
+       fprintf(stderr, "cache-tree invalidate <%s>\n", path);
+#endif
+
        if (!it)
                return;
        slash = strchr(path, '/');
@@ -331,11 +335,11 @@ static int update_one(struct cache_tree *it,
                offset += sprintf(buffer + offset,
                                  "%o %.*s", mode, entlen, path + baselen);
                buffer[offset++] = 0;
-               memcpy(buffer + offset, sha1, 20);
+               hashcpy((unsigned char*)buffer + offset, sha1);
                offset += 20;
 
 #if DEBUG
-               fprintf(stderr, "cache-tree %o %.*s\n",
+               fprintf(stderr, "cache-tree update-one %o %.*s\n",
                        mode, entlen, path + baselen);
 #endif
        }
@@ -351,7 +355,7 @@ static int update_one(struct cache_tree *it,
        free(buffer);
        it->entry_count = i;
 #if DEBUG
-       fprintf(stderr, "cache-tree (%d ent, %d subtree) %s\n",
+       fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n",
                it->entry_count, it->subtree_nr,
                sha1_to_hex(it->sha1));
 #endif
@@ -408,7 +412,7 @@ static void *write_one(struct cache_tree *it,
 #endif
 
        if (0 <= it->entry_count) {
-               memcpy(buffer + *offset, it->sha1, 20);
+               hashcpy((unsigned char*)buffer + *offset, it->sha1);
                *offset += 20;
        }
        for (i = 0; i < it->subtree_nr; i++) {
@@ -440,6 +444,8 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
 {
        const char *buf = *buffer;
        unsigned long size = *size_p;
+       const char *cp;
+       char *ep;
        struct cache_tree *it;
        int i, subtree_nr;
 
@@ -453,7 +459,14 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
                goto free_return;
        buf++; size--;
        it = cache_tree();
-       if (sscanf(buf, "%d %d\n", &it->entry_count, &subtree_nr) != 2)
+
+       cp = buf;
+       it->entry_count = strtol(cp, &ep, 10);
+       if (cp == ep)
+               goto free_return;
+       cp = ep;
+       subtree_nr = strtol(cp, &ep, 10);
+       if (cp == ep)
                goto free_return;
        while (size && *buf && *buf != '\n') {
                size--;
@@ -465,7 +478,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
        if (0 <= it->entry_count) {
                if (size < 20)
                        goto free_return;
-               memcpy(it->sha1, buf, 20);
+               hashcpy(it->sha1, (unsigned char*)buf);
                buf += 20;
                size -= 20;
        }
@@ -516,3 +529,29 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size)
                return NULL; /* not the whole tree */
        return read_one(&buffer, &size);
 }
+
+struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)
+{
+       while (*path) {
+               const char *slash;
+               struct cache_tree_sub *sub;
+
+               slash = strchr(path, '/');
+               if (!slash)
+                       slash = path + strlen(path);
+               /* between path and slash is the name of the
+                * subtree to look for.
+                */
+               sub = find_subtree(it, path, slash - path, 0);
+               if (!sub)
+                       return NULL;
+               it = sub->cache_tree;
+               if (slash)
+                       while (*slash && *slash == '/')
+                               slash++;
+               if (!slash || !*slash)
+                       return it; /* prefix ended with slashes */
+               path = slash;
+       }
+       return it;
+}