diff options
author | Junio C Hamano <junkio@cox.net> | 2006-04-27 01:33:07 -0700 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-04-27 01:33:07 -0700 |
commit | 7927a55d5bde25702dca4fb1a7d6eb7ef61110ba (patch) | |
tree | ed3c465e99f20045c9e5e85d4123e2820a097066 /read-tree.c | |
parent | b34c39cf31e370dad3bcfba29ee8cd023c40fd6b (diff) | |
download | git-7927a55d5bde25702dca4fb1a7d6eb7ef61110ba.tar.gz |
read-tree: teach 1-way merege and plain read to prime cache-tree.
This teaches read-tree to fully populate valid cache-tree when
reading a tree from scratch, or reading a single tree into an
existing index, reusing only the cached stat information (i.e.
one-way merge). We have already taught update-index about cache-tree,
so "git checkout" followed by updates to a few path followed by
a "git commit" would become very efficient.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'read-tree.c')
-rw-r--r-- | read-tree.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/read-tree.c b/read-tree.c index ab516824ef..66c0120f13 100644 --- a/read-tree.c +++ b/read-tree.c @@ -725,6 +725,39 @@ static int read_cache_unmerged(void) return deleted; } +static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) +{ + struct tree_entry_list *ent; + int cnt; + + memcpy(it->sha1, tree->object.sha1, 20); + for (cnt = 0, ent = tree->entries; ent; ent = ent->next) { + if (!ent->directory) + cnt++; + else { + struct cache_tree_sub *sub; + struct tree *subtree = (struct tree *)ent->item.tree; + if (!subtree->object.parsed) + parse_tree(subtree); + sub = cache_tree_sub(it, ent->name); + sub->cache_tree = cache_tree(); + prime_cache_tree_rec(sub->cache_tree, subtree); + cnt += sub->cache_tree->entry_count; + } + } + it->entry_count = cnt; +} + +static void prime_cache_tree(void) +{ + struct tree *tree = (struct tree *)trees->item; + if (!tree) + return; + active_cache_tree = cache_tree(); + prime_cache_tree_rec(active_cache_tree, tree); + +} + static const char read_tree_usage[] = "git-read-tree (<sha> | -m [--aggressive] [-u | -i] <sha1> [<sha2> [<sha3>]])"; static struct cache_file cache_file; @@ -839,6 +872,18 @@ int main(int argc, char **argv) } unpack_trees(fn); + + /* + * When reading only one tree (either the most basic form, + * "-m ent" or "--reset ent" form), we can obtain a fully + * valid cache-tree because the index must match exactly + * what came from the tree. + */ + if (trees->item && (!merge || (stage == 2))) { + cache_tree_free(&active_cache_tree); + prime_cache_tree(); + } + if (write_cache(newfd, active_cache, active_nr) || commit_index_file(&cache_file)) die("unable to write new index file"); |