diff options
author | Junio C Hamano <gitster@pobox.com> | 2009-06-20 21:47:30 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2009-06-20 21:47:30 -0700 |
commit | c28a17f270a51a4ed5e432e83c0ed962361a37c9 (patch) | |
tree | 6b7c829a56d0e09d8f0b80adb1d035889ce14d77 /cache-tree.c | |
parent | deded16d151ff0f7b80ed21a518928daff09c14c (diff) | |
parent | a0919ced8a5efe938cf97c74a0f851cbbe00aaf6 (diff) | |
download | git-c28a17f270a51a4ed5e432e83c0ed962361a37c9.tar.gz git-c28a17f270a51a4ed5e432e83c0ed962361a37c9.tar.xz |
Merge branch 'jc/cache-tree'
* jc/cache-tree:
Avoid "diff-index --cached" optimization under --find-copies-harder
Optimize "diff-index --cached" using cache-tree
t4007: modernize the style
cache-tree.c::cache_tree_find(): simplify internal API
write-tree --ignore-cache-tree
Diffstat (limited to 'cache-tree.c')
-rw-r--r-- | cache-tree.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/cache-tree.c b/cache-tree.c index 37bf35e63..16a65dfac 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -514,6 +514,8 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size) static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path) { + if (!it) + return NULL; while (*path) { const char *slash; struct cache_tree_sub *sub; @@ -538,28 +540,32 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat return it; } -int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix) +int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix) { int entries, was_valid, newfd; + struct lock_file *lock_file; /* * We can't free this memory, it becomes part of a linked list * parsed atexit() */ - struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); + lock_file = xcalloc(1, sizeof(struct lock_file)); newfd = hold_locked_index(lock_file, 1); entries = read_cache(); if (entries < 0) return WRITE_TREE_UNREADABLE_INDEX; + if (flags & WRITE_TREE_IGNORE_CACHE_TREE) + cache_tree_free(&(active_cache_tree)); if (!active_cache_tree) active_cache_tree = cache_tree(); was_valid = cache_tree_fully_valid(active_cache_tree); - if (!was_valid) { + int missing_ok = flags & WRITE_TREE_MISSING_OK; + if (cache_tree_update(active_cache_tree, active_cache, active_nr, missing_ok, 0) < 0) @@ -625,3 +631,35 @@ void prime_cache_tree(struct cache_tree **it, struct tree *tree) *it = cache_tree(); prime_cache_tree_rec(*it, tree); } + +/* + * find the cache_tree that corresponds to the current level without + * exploding the full path into textual form. The root of the + * cache tree is given as "root", and our current level is "info". + * (1) When at root level, info->prev is NULL, so it is "root" itself. + * (2) Otherwise, find the cache_tree that corresponds to one level + * above us, and find ourselves in there. + */ +static struct cache_tree *find_cache_tree_from_traversal(struct cache_tree *root, + struct traverse_info *info) +{ + struct cache_tree *our_parent; + + if (!info->prev) + return root; + our_parent = find_cache_tree_from_traversal(root, info->prev); + return cache_tree_find(our_parent, info->name.path); +} + +int cache_tree_matches_traversal(struct cache_tree *root, + struct name_entry *ent, + struct traverse_info *info) +{ + struct cache_tree *it; + + it = find_cache_tree_from_traversal(root, info); + it = cache_tree_find(it, ent->path); + if (it && it->entry_count > 0 && !hashcmp(ent->sha1, it->sha1)) + return it->entry_count; + return 0; +} |