clone: check connectivity even if clone is partial

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>

Jonathan Tan committed Jul 6, 2018 at 12:34 UTC a7e67c11b8b983b4a9f56f0b8990a550946ed6b0
2 files changed +49 -1
builtin/clone.c
+1 -1
@@ -1201,7 +1201,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1201
1202 update_remote_refs(refs, mapped_refs, remote_head_points_at,
1203 branch_top.buf, reflog_msg.buf, transport,
1204 - !is_local && !filter_options.choice);
1204 + !is_local);
1205
1206 update_head(our_head_points_at, remote_head, reflog_msg.buf);
1207
t/t5616-partial-clone.sh
+48
@@ -170,4 +170,52 @@ test_expect_success 'partial clone fetches blobs pointed to by refs even if norm
170 git -C dst fsck
171 '
172
173 +. "$TEST_DIRECTORY"/lib-httpd.sh
174 +start_httpd
175 +
176 +# Converts bytes into a form suitable for inclusion in a sed command. For
177 +# example, "printf 'ab\r\n' | hex_unpack" results in '\x61\x62\x0d\x0a'.
178 +sed_escape () {
179 + perl -e '$/ = undef; $input = <>; print unpack("H2" x length($input), $input)' |
180 + sed 's/\(..\)/\\x\1/g'
181 +}
182 +
183 +test_expect_success 'upon cloning, check that all refs point to objects' '
184 + SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" &&
185 + rm -rf "$SERVER" repo &&
186 + test_create_repo "$SERVER" &&
187 + test_commit -C "$SERVER" foo &&
188 + test_config -C "$SERVER" uploadpack.allowfilter 1 &&
189 + test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 &&
190 +
191 + # Create a tag pointing to a blob.
192 + BLOB=$(echo blob-contents | git -C "$SERVER" hash-object --stdin -w) &&
193 + git -C "$SERVER" tag myblob "$BLOB" &&
194 +
195 + # Craft a packfile not including that blob.
196 + git -C "$SERVER" rev-parse HEAD |
197 + git -C "$SERVER" pack-objects --stdout >incomplete.pack &&
198 +
199 + # Replace the existing packfile with the crafted one. The protocol
200 + # requires that the packfile be sent in sideband 1, hence the extra
201 + # \x01 byte at the beginning.
202 + printf "1,/packfile/!c %04x\\\\x01%s0000" \
203 + "$(($(wc -c <incomplete.pack) + 5))" \
204 + "$(sed_escape <incomplete.pack)" \
205 + >"$HTTPD_ROOT_PATH/one-time-sed" &&
206 +
207 + # Use protocol v2 because the sed command looks for the "packfile"
208 + # section header.
209 + test_config -C "$SERVER" protocol.version 2 &&
210 + test_must_fail git -c protocol.version=2 clone \
211 + --filter=blob:none $HTTPD_URL/one_time_sed/server repo 2>err &&
212 +
213 + grep "did not send all necessary objects" err &&
214 +
215 + # Ensure that the one-time-sed script was used.
216 + ! test -e "$HTTPD_ROOT_PATH/one-time-sed"
217 +'
218 +
219 +stop_httpd
220 +
221 test_done