path: root/cache-tree.c
diff options
authorJonathan Tan <>2018-10-09 18:40:37 (GMT)
committerJunio C Hamano <>2018-10-10 01:20:43 (GMT)
commit2f215ff10bdf02f6c760ea34968fc39ae75ae449 (patch)
treefc0085c157f8dd8304d4b90b9d59e95644e43289 /cache-tree.c
parent2efbb7f5218d5ca9d50cbcb86a365a08b2981d77 (diff)
cache-tree: skip some blob checks in partial clone
In a partial clone, whenever a sparse checkout occurs, the existence of all blobs in the index is verified, whether they are included or excluded by the .git/info/sparse-checkout specification. This significantly degrades performance because a lazy fetch occurs whenever the existence of a missing blob is checked. This is because cache_tree_update() checks the existence of all objects in the index, whether or not CE_SKIP_WORKTREE is set on them. Teach cache_tree_update() to skip checking CE_SKIP_WORKTREE objects when the repository is a partial clone. This improves performance for sparse checkout and also other operations that use cache_tree_update(). Instead of completely removing the check, an argument could be made that the check should instead be replaced by a check that the blob is promised, but for performance reasons, I decided not to do this. If the user needs to verify the repository, it can be done using fsck (which will notify if a tree points to a missing and non-promised blob, whether the blob is included or excluded by the sparse-checkout specification). Signed-off-by: Jonathan Tan <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'cache-tree.c')
1 files changed, 5 insertions, 1 deletions
diff --git a/cache-tree.c b/cache-tree.c
index 5ce5146..f210481 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -326,6 +326,7 @@ static int update_one(struct cache_tree *it,
unsigned mode;
int expected_missing = 0;
int contains_ita = 0;
+ int ce_missing_ok;
path = ce->name;
pathlen = ce_namelen(ce);
@@ -355,8 +356,11 @@ static int update_one(struct cache_tree *it,
+ ce_missing_ok = mode == S_IFGITLINK || missing_ok ||
+ (repository_format_partial_clone &&
+ ce_skip_worktree(ce));
if (is_null_oid(oid) ||
- (mode != S_IFGITLINK && !missing_ok && !has_object_file(oid))) {
+ (!ce_missing_ok && !has_object_file(oid))) {
if (expected_missing)
return -1;