Merge branch 'jt/cache-tree-allow-missing-object-in-partial-clone'
authorJunio C Hamano <gitster@pobox.com>
Fri, 19 Oct 2018 04:34:08 +0000 (13:34 +0900)
committerJunio C Hamano <gitster@pobox.com>
Fri, 19 Oct 2018 04:34:08 +0000 (13:34 +0900)
In a partial clone that will lazily be hydrated from the
originating repository, we generally want to avoid "does this
object exist (locally)?" on objects that we deliberately omitted
when we created the clone. The cache-tree codepath (which is used
to write a tree object out of the index) however insisted that the
object exists, even for paths that are outside of the partial
checkout area. The code has been updated to avoid such a check.

* jt/cache-tree-allow-missing-object-in-partial-clone:
cache-tree: skip some blob checks in partial clone

cache-tree.c
t/t1090-sparse-checkout-scope.sh
index 9c5cf2cc4fdc1f2f4ccc7f352289fe0ec75e8f5d..9d454d24bca62dcdb8c941a64d09b7a53556323a 100644 (file)
@@ -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,
                        i++;
                }
 
+               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))) {
                        strbuf_release(&buffer);
                        if (expected_missing)
                                return -1;
index 25d7c700f6f480076f3ad00e6eeb709f8de517fa..090b7fc3d35d1a46a18b8ae385a7cc1213e6650d 100755 (executable)
@@ -63,4 +63,37 @@ test_expect_success 'return to full checkout of master' '
        test "$(cat b)" = "modified"
 '
 
+test_expect_success 'in partial clone, sparse checkout only fetches needed blobs' '
+       test_create_repo server &&
+       git clone "file://$(pwd)/server" client &&
+
+       test_config -C server uploadpack.allowfilter 1 &&
+       test_config -C server uploadpack.allowanysha1inwant 1 &&
+       echo a >server/a &&
+       echo bb >server/b &&
+       mkdir server/c &&
+       echo ccc >server/c/c &&
+       git -C server add a b c/c &&
+       git -C server commit -m message &&
+
+       test_config -C client core.sparsecheckout 1 &&
+       test_config -C client extensions.partialclone origin &&
+       echo "!/*" >client/.git/info/sparse-checkout &&
+       echo "/a" >>client/.git/info/sparse-checkout &&
+       git -C client fetch --filter=blob:none origin &&
+       git -C client checkout FETCH_HEAD &&
+
+       git -C client rev-list HEAD \
+               --quiet --objects --missing=print >unsorted_actual &&
+       (
+               printf "?" &&
+               git hash-object server/b &&
+               printf "?" &&
+               git hash-object server/c/c
+       ) >unsorted_expect &&
+       sort unsorted_actual >actual &&
+       sort unsorted_expect >expect &&
+       test_cmp expect actual
+'
+
 test_done