summaryrefslogtreecommitdiff
path: root/builtin-read-tree.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-05-28 22:57:47 -0700
committerJunio C Hamano <junkio@cox.net>2006-05-28 22:57:47 -0700
commit3f69d405d749742945afd462bff6541604ecd420 (patch)
tree8abc47e17be2680b2e93f3c8c0e503d66bdee3bc /builtin-read-tree.c
parent7d65848afd42f075f6db0d03da2c9f5a9bac6267 (diff)
parent7d55561986ffe94ca7ca22dc0a6846f698893226 (diff)
downloadgit-3f69d405d749742945afd462bff6541604ecd420.tar.gz
Merge branch 'jc/cache-tree'
* jc/cache-tree: (26 commits) builtin-rm: squelch compiler warnings. git-write-tree writes garbage on sparc64 Fix crash when reading the empty tree fsck-objects: do not segfault on missing tree in cache-tree cache-tree: a bit more debugging support. read-tree: invalidate cache-tree entry when a new index entry is added. Fix test-dump-cache-tree in one-tree disappeared case. fsck-objects: mark objects reachable from cache-tree cache-tree: replace a sscanf() by two strtol() calls cache-tree.c: typefix test-dump-cache-tree: validate the cached data as well. cache_tree_update: give an option to update cache-tree only. read-tree: teach 1-way merege and plain read to prime cache-tree. read-tree: teach 1 and 2 way merges about cache-tree. update-index: when --unresolve, smudge the relevant cache-tree entries. test-dump-cache-tree: report number of subtrees. cache-tree: sort the subtree entries. Teach fsck-objects about cache-tree. index: make the index file format extensible. cache-tree: protect against "git prune". ... Conflicts: Makefile, builtin.h, git.c: resolved the same way as in next.
Diffstat (limited to 'builtin-read-tree.c')
-rw-r--r--builtin-read-tree.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index ec40d013c4..716f792514 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -9,6 +9,7 @@
#include "object.h"
#include "tree.h"
+#include "cache-tree.h"
#include <sys/time.h>
#include <signal.h>
#include "builtin.h"
@@ -427,6 +428,12 @@ static void verify_uptodate(struct cache_entry *ce)
die("Entry '%s' not uptodate. Cannot merge.", ce->name);
}
+static void invalidate_ce_path(struct cache_entry *ce)
+{
+ if (ce)
+ cache_tree_invalidate_path(active_cache_tree, ce->name);
+}
+
/*
* We do not want to remove or overwrite a working tree file that
* is not tracked.
@@ -457,10 +464,13 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
*merge = *old;
} else {
verify_uptodate(old);
+ invalidate_ce_path(old);
}
}
- else
+ else {
verify_absent(merge->name, "overwritten");
+ invalidate_ce_path(merge);
+ }
merge->ce_flags &= ~htons(CE_STAGEMASK);
add_cache_entry(merge, ADD_CACHE_OK_TO_ADD);
@@ -475,6 +485,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old)
verify_absent(ce->name, "removed");
ce->ce_mode = 0;
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD);
+ invalidate_ce_path(ce);
return 1;
}
@@ -750,6 +761,7 @@ static int read_cache_unmerged(void)
struct cache_entry *ce = active_cache[i];
if (ce_stage(ce)) {
deleted++;
+ invalidate_ce_path(ce);
continue;
}
if (deleted)
@@ -760,6 +772,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;
@@ -861,10 +906,9 @@ int cmd_read_tree(int argc, const char **argv, char **envp)
fn = twoway_merge;
break;
case 3:
- fn = threeway_merge;
- break;
default:
fn = threeway_merge;
+ cache_tree_free(&active_cache_tree);
break;
}
@@ -875,6 +919,18 @@ int cmd_read_tree(int argc, const char **argv, char **envp)
}
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 && 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");