Code

Merge branch 'maint'
[git.git] / unpack-trees.c
index 85045fd03fd7ab2a2ad8daf5ec584e010372673b..f561d88156b827b15bad7dd4e00f944718149bd9 100644 (file)
@@ -329,6 +329,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long
 {
        int i, ret, bottom;
        struct tree_desc t[MAX_UNPACK_TREES];
+       void *buf[MAX_UNPACK_TREES];
        struct traverse_info newinfo;
        struct name_entry *p;
 
@@ -346,12 +347,16 @@ static int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long
                const unsigned char *sha1 = NULL;
                if (dirmask & 1)
                        sha1 = names[i].sha1;
-               fill_tree_descriptor(t+i, sha1);
+               buf[i] = fill_tree_descriptor(t+i, sha1);
        }
 
        bottom = switch_cache_bottom(&newinfo);
        ret = traverse_trees(n, t, &newinfo);
        restore_cache_bottom(&newinfo, bottom);
+
+       for (i = 0; i < n; i++)
+               free(buf[i]);
+
        return ret;
 }
 
@@ -522,9 +527,17 @@ static int find_cache_pos(struct traverse_info *info,
                const char *ce_name, *ce_slash;
                int cmp, ce_len;
 
-               if (!ce_in_traverse_path(ce, info))
+               if (ce->ce_flags & CE_UNPACKED) {
+                       /*
+                        * cache_bottom entry is already unpacked, so
+                        * we can never match it; don't check it
+                        * again.
+                        */
+                       if (pos == o->cache_bottom)
+                               ++o->cache_bottom;
                        continue;
-               if (ce->ce_flags & CE_UNPACKED)
+               }
+               if (!ce_in_traverse_path(ce, info))
                        continue;
                ce_name = ce->name + pfxlen;
                ce_slash = strchr(ce_name, '/');