summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-11-16 17:35:47 -0800
committerJunio C Hamano <gitster@pobox.com>2016-11-16 17:38:25 -0800
commitcdeb4042e35b108e254795cd134d5039e772a4e3 (patch)
treea296ecc15a39f030c566a7587c86ae75b90de029
parent0b65a8dbdb38962e700ee16776a3042beb489060 (diff)
downloadgit-jc/cache-tree-freshen.tar.gz
cache-tree: make sure to "touch" tree objects the cache-tree recordsjc/cache-tree-freshen
The cache_tree_fully_valid() function is called by callers that want to know if they need to call cache_tree_update(), i.e. as an attempt to optimize. They all want to have a fully valid cache-tree in the end so that they can write a tree object out. We used to check if the cached tree object is up-to-date (i.e. the index entires covered by the cache-tree entry hasn't been changed since the roll-up hash was computed for the cache-tree entry) and made sure the tree object is already in the object store. Since the top-level tree we would soon be asked to write out (and would find in the object store) may not be anchored to any refs or commits immediately, freshen the tree object when it happens. Similarly, when we actually compute the cache-tree entries in cache_tree_update(), we refrained from writing a tree object out when it already exists in the object store. We would want to freshen the tree object in that case to protect it from premature pruning. Strictly speaking, freshing these tree objects at each and every level is probably unnecessary, given that anything reachable from a young object inherits the youth from the referring object to be protected from pruning. It should be sufficient to freshen only the very top-level tree instead. Benchmarking and optimization is left as an exercise for later days. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--cache-tree.c6
-rw-r--r--cache.h1
-rw-r--r--sha1_file.c9
3 files changed, 11 insertions, 5 deletions
diff --git a/cache-tree.c b/cache-tree.c
index 3ebf9c3aa4..c8c74a1e07 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -225,7 +225,7 @@ int cache_tree_fully_valid(struct cache_tree *it)
int i;
if (!it)
return 0;
- if (it->entry_count < 0 || !has_sha1_file(it->sha1))
+ if (it->entry_count < 0 || !freshen_object(it->sha1))
return 0;
for (i = 0; i < it->subtree_nr; i++) {
if (!cache_tree_fully_valid(it->down[i]->cache_tree))
@@ -253,7 +253,7 @@ static int update_one(struct cache_tree *it,
*skip_count = 0;
- if (0 <= it->entry_count && has_sha1_file(it->sha1))
+ if (0 <= it->entry_count && freshen_object(it->sha1))
return it->entry_count;
/*
@@ -393,7 +393,7 @@ static int update_one(struct cache_tree *it,
if (repair) {
unsigned char sha1[20];
hash_sha1_file(buffer.buf, buffer.len, tree_type, sha1);
- if (has_sha1_file(sha1))
+ if (freshen_object(sha1))
hashcpy(it->sha1, sha1);
else
to_invalidate = 1;
diff --git a/cache.h b/cache.h
index 4ff196c259..72c0b321ac 100644
--- a/cache.h
+++ b/cache.h
@@ -1077,6 +1077,7 @@ extern int sha1_object_info(const unsigned char *, unsigned long *);
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
+extern int freshen_object(const unsigned char *);
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
extern int git_open_noatime(const char *name);
diff --git a/sha1_file.c b/sha1_file.c
index d0f2aa029b..9acce3d3b8 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3151,6 +3151,11 @@ static int freshen_packed_object(const unsigned char *sha1)
return 1;
}
+int freshen_object(const unsigned char *sha1)
+{
+ return freshen_packed_object(sha1) || freshen_loose_object(sha1);
+}
+
int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1)
{
char hdr[32];
@@ -3160,7 +3165,7 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
* it out into .git/objects/??/?{38} file.
*/
write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
- if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
+ if (freshen_object(sha1))
return 0;
return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
}
@@ -3178,7 +3183,7 @@ int hash_sha1_file_literally(const void *buf, unsigned long len, const char *typ
if (!(flags & HASH_WRITE_OBJECT))
goto cleanup;
- if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
+ if (freshen_object(sha1))
goto cleanup;
status = write_loose_object(sha1, header, hdrlen, buf, len, 0);