]> granicus.if.org Git - git/commitdiff
clone: check connectivity even if clone is partial
authorJonathan Tan <jonathantanmy@google.com>
Fri, 6 Jul 2018 19:34:10 +0000 (12:34 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Jul 2018 19:37:38 +0000 (12:37 -0700)
The commit that introduced the partial clone feature - 548719fbdc
("clone: partial clone", 2017-12-08) - excluded connectivity checks
for partial clones, but this also meant that it is possible for a clone
to succeed, yet not have all objects either present or promised.
Specifically, if cloning with --filter=blob:none from a repository that
has a tag pointing to a blob, and the blob is not sent in the packfile,
the clone will pass, even if the blob is not referenced by any tree in
the packfile.

Turn on connectivity checks for partial clone.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/clone.c
t/t5616-partial-clone.sh

index 8f86d99c51f099805c752ba460cf99e6a77891b0..fa535507587959a345bcfa65cc17b760b95039ab 100644 (file)
@@ -1201,7 +1201,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
        update_remote_refs(refs, mapped_refs, remote_head_points_at,
                           branch_top.buf, reflog_msg.buf, transport,
-                          !is_local && !filter_options.choice);
+                          !is_local);
 
        update_head(our_head_points_at, remote_head, reflog_msg.buf);
 
index 8a2bf86491f6b3cd23cad5b15f4e5df2c55589e4..44d8e80171a646bc6b4172a38763ca6355c94901 100755 (executable)
@@ -170,4 +170,52 @@ test_expect_success 'partial clone fetches blobs pointed to by refs even if norm
        git -C dst fsck
 '
 
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+# Converts bytes into a form suitable for inclusion in a sed command. For
+# example, "printf 'ab\r\n' | hex_unpack" results in '\x61\x62\x0d\x0a'.
+sed_escape () {
+       perl -e '$/ = undef; $input = <>; print unpack("H2" x length($input), $input)' |
+               sed 's/\(..\)/\\x\1/g'
+}
+
+test_expect_success 'upon cloning, check that all refs point to objects' '
+       SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" &&
+       rm -rf "$SERVER" repo &&
+       test_create_repo "$SERVER" &&
+       test_commit -C "$SERVER" foo &&
+       test_config -C "$SERVER" uploadpack.allowfilter 1 &&
+       test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 &&
+
+       # Create a tag pointing to a blob.
+       BLOB=$(echo blob-contents | git -C "$SERVER" hash-object --stdin -w) &&
+       git -C "$SERVER" tag myblob "$BLOB" &&
+
+       # Craft a packfile not including that blob.
+       git -C "$SERVER" rev-parse HEAD |
+               git -C "$SERVER" pack-objects --stdout >incomplete.pack &&
+
+       # Replace the existing packfile with the crafted one. The protocol
+       # requires that the packfile be sent in sideband 1, hence the extra
+       # \x01 byte at the beginning.
+       printf "1,/packfile/!c %04x\\\\x01%s0000" \
+               "$(($(wc -c <incomplete.pack) + 5))" \
+               "$(sed_escape <incomplete.pack)" \
+               >"$HTTPD_ROOT_PATH/one-time-sed" &&
+
+       # Use protocol v2 because the sed command looks for the "packfile"
+       # section header.
+       test_config -C "$SERVER" protocol.version 2 &&
+       test_must_fail git -c protocol.version=2 clone \
+               --filter=blob:none $HTTPD_URL/one_time_sed/server repo 2>err &&
+
+       grep "did not send all necessary objects" err &&
+
+       # Ensure that the one-time-sed script was used.
+       ! test -e "$HTTPD_ROOT_PATH/one-time-sed"
+'
+
+stop_httpd
+
 test_done