#include "cache-tree.h"
#include "object-store.h"
#include "replace-object.h"
+#include "promisor-remote.h"
-#ifndef DEBUG
-#define DEBUG 0
+#ifndef DEBUG_CACHE_TREE
+#define DEBUG_CACHE_TREE 0
#endif
struct cache_tree *cache_tree(void)
int namelen;
struct cache_tree_sub *down;
-#if DEBUG
+#if DEBUG_CACHE_TREE
fprintf(stderr, "cache-tree invalidate <%s>\n", path);
#endif
int i;
if (!it)
return 0;
- if (it->entry_count < 0 || !has_sha1_file(it->oid.hash))
+ if (it->entry_count < 0 || !has_object_file(&it->oid))
return 0;
for (i = 0; i < it->subtree_nr; i++) {
if (!cache_tree_fully_valid(it->down[i]->cache_tree))
*skip_count = 0;
- if (0 <= it->entry_count && has_sha1_file(it->oid.hash))
+ if (0 <= it->entry_count && has_object_file(&it->oid))
return it->entry_count;
/*
}
ce_missing_ok = mode == S_IFGITLINK || missing_ok ||
- (repository_format_partial_clone &&
+ (has_promisor_remote() &&
ce_skip_worktree(ce));
if (is_null_oid(oid) ||
(!ce_missing_ok && !has_object_file(oid))) {
strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
strbuf_add(&buffer, oid->hash, the_hash_algo->rawsz);
-#if DEBUG
+#if DEBUG_CACHE_TREE
fprintf(stderr, "cache-tree update-one %o %.*s\n",
mode, entlen, path + baselen);
#endif
if (repair) {
struct object_id oid;
- hash_object_file(buffer.buf, buffer.len, tree_type, &oid);
- if (has_object_file(&oid))
+ hash_object_file(the_hash_algo, buffer.buf, buffer.len,
+ tree_type, &oid);
+ if (has_object_file_with_flags(&oid, OBJECT_INFO_SKIP_FETCH_OBJECT))
oidcpy(&it->oid, &oid);
else
to_invalidate = 1;
} else if (dryrun) {
- hash_object_file(buffer.buf, buffer.len, tree_type, &it->oid);
+ hash_object_file(the_hash_algo, buffer.buf, buffer.len,
+ tree_type, &it->oid);
} else if (write_object_file(buffer.buf, buffer.len, tree_type,
&it->oid)) {
strbuf_release(&buffer);
strbuf_release(&buffer);
it->entry_count = to_invalidate ? -1 : i - *skip_count;
-#if DEBUG
+#if DEBUG_CACHE_TREE
fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n",
it->entry_count, it->subtree_nr,
oid_to_hex(&it->oid));
}
static void write_one(struct strbuf *buffer, struct cache_tree *it,
- const char *path, int pathlen)
+ const char *path, int pathlen)
{
int i;
strbuf_add(buffer, path, pathlen);
strbuf_addf(buffer, "%c%d %d\n", 0, it->entry_count, it->subtree_nr);
-#if DEBUG
+#if DEBUG_CACHE_TREE
if (0 <= it->entry_count)
fprintf(stderr, "cache-tree <%.*s> (%d ent, %d subtree) %s\n",
pathlen, path, it->entry_count, it->subtree_nr,
size -= rawsz;
}
-#if DEBUG
+#if DEBUG_CACHE_TREE
if (0 <= it->entry_count)
fprintf(stderr, "cache-tree <%s> (%d ent, %d subtree) %s\n",
*buffer, it->entry_count, subtree_nr,
return it;
}
+static int write_index_as_tree_internal(struct object_id *oid,
+ struct index_state *index_state,
+ int cache_tree_valid,
+ int flags,
+ const char *prefix)
+{
+ if (flags & WRITE_TREE_IGNORE_CACHE_TREE) {
+ cache_tree_free(&index_state->cache_tree);
+ cache_tree_valid = 0;
+ }
+
+ if (!index_state->cache_tree)
+ index_state->cache_tree = cache_tree();
+
+ if (!cache_tree_valid && cache_tree_update(index_state, flags) < 0)
+ return WRITE_TREE_UNMERGED_INDEX;
+
+ if (prefix) {
+ struct cache_tree *subtree;
+ subtree = cache_tree_find(index_state->cache_tree, prefix);
+ if (!subtree)
+ return WRITE_TREE_PREFIX_ERROR;
+ oidcpy(oid, &subtree->oid);
+ }
+ else
+ oidcpy(oid, &index_state->cache_tree->oid);
+
+ return 0;
+}
+
+struct tree* write_in_core_index_as_tree(struct repository *repo) {
+ struct object_id o;
+ int was_valid, ret;
+
+ struct index_state *index_state = repo->index;
+ was_valid = index_state->cache_tree &&
+ cache_tree_fully_valid(index_state->cache_tree);
+
+ ret = write_index_as_tree_internal(&o, index_state, was_valid, 0, NULL);
+ if (ret == WRITE_TREE_UNMERGED_INDEX) {
+ int i;
+ fprintf(stderr, "BUG: There are unmerged index entries:\n");
+ for (i = 0; i < index_state->cache_nr; i++) {
+ const struct cache_entry *ce = index_state->cache[i];
+ if (ce_stage(ce))
+ fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
+ (int)ce_namelen(ce), ce->name);
+ }
+ BUG("unmerged index entries when writing inmemory index");
+ }
+
+ return lookup_tree(repo, &index_state->cache_tree->oid);
+}
+
+
int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
{
int entries, was_valid;
struct lock_file lock_file = LOCK_INIT;
- int ret = 0;
+ int ret;
hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR);
ret = WRITE_TREE_UNREADABLE_INDEX;
goto out;
}
- if (flags & WRITE_TREE_IGNORE_CACHE_TREE)
- cache_tree_free(&index_state->cache_tree);
- if (!index_state->cache_tree)
- index_state->cache_tree = cache_tree();
+ was_valid = !(flags & WRITE_TREE_IGNORE_CACHE_TREE) &&
+ index_state->cache_tree &&
+ cache_tree_fully_valid(index_state->cache_tree);
- was_valid = cache_tree_fully_valid(index_state->cache_tree);
- if (!was_valid) {
- if (cache_tree_update(index_state, flags) < 0) {
- ret = WRITE_TREE_UNMERGED_INDEX;
- goto out;
- }
+ ret = write_index_as_tree_internal(oid, index_state, was_valid, flags,
+ prefix);
+ if (!ret && !was_valid) {
write_locked_index(index_state, &lock_file, COMMIT_LOCK);
/* Not being able to write is fine -- we are only interested
* in updating the cache-tree part, and if the next caller
*/
}
- if (prefix) {
- struct cache_tree *subtree;
- subtree = cache_tree_find(index_state->cache_tree, prefix);
- if (!subtree) {
- ret = WRITE_TREE_PREFIX_ERROR;
- goto out;
- }
- oidcpy(oid, &subtree->oid);
- }
- else
- oidcpy(oid, &index_state->cache_tree->oid);
-
out:
rollback_lock_file(&lock_file);
return ret;
}
-static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
+static void prime_cache_tree_rec(struct repository *r,
+ struct cache_tree *it,
+ struct tree *tree)
{
struct tree_desc desc;
struct name_entry entry;
cnt++;
else {
struct cache_tree_sub *sub;
- struct tree *subtree = lookup_tree(the_repository,
- entry.oid);
+ struct tree *subtree = lookup_tree(r, &entry.oid);
if (!subtree->object.parsed)
parse_tree(subtree);
sub = cache_tree_sub(it, entry.path);
sub->cache_tree = cache_tree();
- prime_cache_tree_rec(sub->cache_tree, subtree);
+ prime_cache_tree_rec(r, sub->cache_tree, subtree);
cnt += sub->cache_tree->entry_count;
}
}
it->entry_count = cnt;
}
-void prime_cache_tree(struct index_state *istate, struct tree *tree)
+void prime_cache_tree(struct repository *r,
+ struct index_state *istate,
+ struct tree *tree)
{
cache_tree_free(&istate->cache_tree);
istate->cache_tree = cache_tree();
- prime_cache_tree_rec(istate->cache_tree, tree);
+ prime_cache_tree_rec(r, istate->cache_tree, tree);
istate->cache_changed |= CACHE_TREE_CHANGED;
}
if (!info->prev)
return root;
our_parent = find_cache_tree_from_traversal(root, info->prev);
- return cache_tree_find(our_parent, info->name.path);
+ return cache_tree_find(our_parent, info->name);
}
int cache_tree_matches_traversal(struct cache_tree *root,
it = find_cache_tree_from_traversal(root, info);
it = cache_tree_find(it, ent->path);
- if (it && it->entry_count > 0 && oideq(ent->oid, &it->oid))
+ if (it && it->entry_count > 0 && oideq(&ent->oid, &it->oid))
return it->entry_count;
return 0;
}
-static void verify_one(struct index_state *istate,
+static void verify_one(struct repository *r,
+ struct index_state *istate,
struct cache_tree *it,
struct strbuf *path)
{
for (i = 0; i < it->subtree_nr; i++) {
strbuf_addf(path, "%s/", it->down[i]->name);
- verify_one(istate, it->down[i]->cache_tree, path);
+ verify_one(r, istate, it->down[i]->cache_tree, path);
strbuf_setlen(path, len);
}
if (it->entry_count < 0 ||
/* no verification on tests (t7003) that replace trees */
- lookup_replace_object(the_repository, &it->oid) != &it->oid)
+ lookup_replace_object(r, &it->oid) != &it->oid)
return;
if (path->len) {
i++;
}
strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0');
- strbuf_add(&tree_buf, oid->hash, the_hash_algo->rawsz);
+ strbuf_add(&tree_buf, oid->hash, r->hash_algo->rawsz);
}
- hash_object_file(tree_buf.buf, tree_buf.len, tree_type, &new_oid);
+ hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, tree_type,
+ &new_oid);
if (!oideq(&new_oid, &it->oid))
BUG("cache-tree for path %.*s does not match. "
"Expected %s got %s", len, path->buf,
strbuf_release(&tree_buf);
}
-void cache_tree_verify(struct index_state *istate)
+void cache_tree_verify(struct repository *r, struct index_state *istate)
{
struct strbuf path = STRBUF_INIT;
if (!istate->cache_tree)
return;
- verify_one(istate, istate->cache_tree, &path);
+ verify_one(r, istate, istate->cache_tree, &path);
strbuf_release(&path);
}