documentation: add documentation for the bitmap format
[gitweb.git] / cache-tree.c
index 2c10b2e2dd65ea70001624457bb44fb4ee6ab755..0bbec432165874bd36b1f220301de7f1363626dc 100644 (file)
@@ -149,7 +149,7 @@ void cache_tree_invalidate_path(struct cache_tree *it, const char *path)
                cache_tree_invalidate_path(down->cache_tree, slash + 1);
 }
 
-static int verify_cache(struct cache_entry **cache,
+static int verify_cache(const struct cache_entry * const *cache,
                        int entries, int flags)
 {
        int i, funny;
@@ -158,7 +158,7 @@ static int verify_cache(struct cache_entry **cache,
        /* Verify that the tree is merged */
        funny = 0;
        for (i = 0; i < entries; i++) {
-               struct cache_entry *ce = cache[i];
+               const struct cache_entry *ce = cache[i];
                if (ce_stage(ce)) {
                        if (silent)
                                return -1;
@@ -234,7 +234,7 @@ int cache_tree_fully_valid(struct cache_tree *it)
 }
 
 static int update_one(struct cache_tree *it,
-                     struct cache_entry **cache,
+                     const struct cache_entry * const *cache,
                      int entries,
                      const char *base,
                      int baselen,
@@ -244,6 +244,7 @@ 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 to_invalidate = 0;
        int i;
 
        *skip_count = 0;
@@ -264,7 +265,7 @@ static int update_one(struct cache_tree *it,
         */
        i = 0;
        while (i < entries) {
-               struct cache_entry *ce = cache[i];
+               const struct cache_entry *ce = cache[i];
                struct cache_tree_sub *sub;
                const char *path, *slash;
                int pathlen, sublen, subcnt, subskip;
@@ -311,7 +312,7 @@ static int update_one(struct cache_tree *it,
 
        i = 0;
        while (i < entries) {
-               struct cache_entry *ce = cache[i];
+               const struct cache_entry *ce = cache[i];
                struct cache_tree_sub *sub;
                const char *path, *slash;
                int pathlen, entlen;
@@ -333,6 +334,8 @@ static int update_one(struct cache_tree *it,
                        i += sub->count;
                        sha1 = sub->cache_tree->sha1;
                        mode = S_IFDIR;
+                       if (sub->cache_tree->entry_count < 0)
+                               to_invalidate = 1;
                }
                else {
                        sha1 = ce->sha1;
@@ -356,8 +359,15 @@ static int update_one(struct cache_tree *it,
                        continue;
                }
 
-               if (ce->ce_flags & CE_INTENT_TO_ADD)
+               /*
+                * CE_INTENT_TO_ADD entries exist on on-disk index but
+                * they are not part of generated trees. Invalidate up
+                * to root to force cache-tree users to read elsewhere.
+                */
+               if (ce->ce_flags & CE_INTENT_TO_ADD) {
+                       to_invalidate = 1;
                        continue;
+               }
 
                strbuf_grow(&buffer, entlen + 100);
                strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
@@ -377,7 +387,7 @@ static int update_one(struct cache_tree *it,
        }
 
        strbuf_release(&buffer);
-       it->entry_count = i - *skip_count;
+       it->entry_count = to_invalidate ? -1 : i - *skip_count;
 #if DEBUG
        fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n",
                it->entry_count, it->subtree_nr,
@@ -387,7 +397,7 @@ static int update_one(struct cache_tree *it,
 }
 
 int cache_tree_update(struct cache_tree *it,
-                     struct cache_entry **cache,
+                     const struct cache_entry * const *cache,
                      int entries,
                      int flags)
 {
@@ -589,8 +599,8 @@ int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
        was_valid = cache_tree_fully_valid(active_cache_tree);
        if (!was_valid) {
                if (cache_tree_update(active_cache_tree,
-                                     active_cache, active_nr,
-                                     flags) < 0)
+                                     (const struct cache_entry * const *)active_cache,
+                                     active_nr, flags) < 0)
                        return WRITE_TREE_UNMERGED_INDEX;
                if (0 <= newfd) {
                        if (!write_cache(newfd, active_cache, active_nr) &&
@@ -691,5 +701,6 @@ int update_main_cache_tree(int flags)
        if (!the_index.cache_tree)
                the_index.cache_tree = cache_tree();
        return cache_tree_update(the_index.cache_tree,
-                                the_index.cache, the_index.cache_nr, flags);
+                                (const struct cache_entry * const *)the_index.cache,
+                                the_index.cache_nr, flags);
 }