Skip to content

Commit a7e67c1

Browse files
jonathantanmygitster
authored andcommitted
clone: check connectivity even if clone is partial
The commit that introduced the partial clone feature - 548719f ("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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a0c9016 commit a7e67c1

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

builtin/clone.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12011201

12021202
update_remote_refs(refs, mapped_refs, remote_head_points_at,
12031203
branch_top.buf, reflog_msg.buf, transport,
1204-
!is_local && !filter_options.choice);
1204+
!is_local);
12051205

12061206
update_head(our_head_points_at, remote_head, reflog_msg.buf);
12071207

t/t5616-partial-clone.sh

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,52 @@ test_expect_success 'partial clone fetches blobs pointed to by refs even if norm
170170
git -C dst fsck
171171
'
172172

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+
173221
test_done

0 commit comments

Comments
 (0)