static int do_invalidate_path(struct cache_tree *it, const char *path) { /* a/b/c * ==> invalidate self * ==> find "a", have it invalidate "b/c" * a * ==> invalidate self * ==> if "a" exists as a subtree, remove it. */ const char *slash; int namelen; struct cache_tree_sub *down; #if DEBUG fprintf(stderr, "cache-tree invalidate <%s>\n", path); #endif if (!it) return 0; slash = strchrnul(path, '/'); namelen = slash - path; it->entry_count = -1; if (!*slash) { int pos; pos = subtree_pos(it, path, namelen); if (0 <= pos) { cache_tree_free(&it->down[pos]->cache_tree); free(it->down[pos]); /* 0 1 2 3 4 5 * ^ ^subtree_nr = 6 * pos * move 4 and 5 up one place (2 entries) * 2 = 6 - 3 - 1 = subtree_nr - pos - 1 */ memmove(it->down+pos, it->down+pos+1, sizeof(struct cache_tree_sub *) * (it->subtree_nr - pos - 1)); it->subtree_nr--; } return 1; } down = find_subtree(it, path, namelen, 0); if (down) do_invalidate_path(down->cache_tree, slash + 1); return 1; }
void cache_tree_invalidate_path(struct index_state *istate, const char *path) { if (do_invalidate_path(istate->cache_tree, path)) istate->cache_changed |= CACHE_TREE_CHANGED; }