cache-tree: Write updated cache-tree after commit
[gitweb.git] / cache-tree.c
index 0bbec432165874bd36b1f220301de7f1363626dc..f951d7d3c4d8ec8f67c896d835cef16b74c6f171 100644 (file)
@@ -75,11 +75,7 @@ static struct cache_tree_sub *find_subtree(struct cache_tree *it,
                return NULL;
 
        pos = -pos-1;
-       if (it->subtree_alloc <= it->subtree_nr) {
-               it->subtree_alloc = alloc_nr(it->subtree_alloc);
-               it->down = xrealloc(it->down, it->subtree_alloc *
-                                   sizeof(*it->down));
-       }
+       ALLOC_GROW(it->down, it->subtree_nr + 1, it->subtree_alloc);
        it->subtree_nr++;
 
        down = xmalloc(sizeof(*down) + pathlen + 1);
@@ -121,11 +117,11 @@ void cache_tree_invalidate_path(struct cache_tree *it, const char *path)
 
        if (!it)
                return;
-       slash = strchr(path, '/');
+       slash = strchrnul(path, '/');
+       namelen = slash - path;
        it->entry_count = -1;
-       if (!slash) {
+       if (!*slash) {
                int pos;
-               namelen = strlen(path);
                pos = subtree_pos(it, path, namelen);
                if (0 <= pos) {
                        cache_tree_free(&it->down[pos]->cache_tree);
@@ -143,7 +139,6 @@ void cache_tree_invalidate_path(struct cache_tree *it, const char *path)
                }
                return;
        }
-       namelen = slash - path;
        down = find_subtree(it, path, namelen, 0);
        if (down)
                cache_tree_invalidate_path(down->cache_tree, slash + 1);
@@ -244,9 +239,12 @@ static int update_one(struct cache_tree *it,
        struct strbuf buffer;
        int missing_ok = flags & WRITE_TREE_MISSING_OK;
        int dryrun = flags & WRITE_TREE_DRY_RUN;
+       int repair = flags & WRITE_TREE_REPAIR;
        int to_invalidate = 0;
        int i;
 
+       assert(!(dryrun && repair));
+
        *skip_count = 0;
 
        if (0 <= it->entry_count && has_sha1_file(it->sha1))
@@ -379,7 +377,14 @@ static int update_one(struct cache_tree *it,
 #endif
        }
 
-       if (dryrun)
+       if (repair) {
+               unsigned char sha1[20];
+               hash_sha1_file(buffer.buf, buffer.len, tree_type, sha1);
+               if (has_sha1_file(sha1))
+                       hashcpy(it->sha1, sha1);
+               else
+                       to_invalidate = 1;
+       } else if (dryrun)
                hash_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1);
        else if (write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1)) {
                strbuf_release(&buffer);
@@ -554,22 +559,19 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat
                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.
+               slash = strchrnul(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;
+               while (*path == '/')
+                       path++;
        }
        return it;
 }