Skip to content

Commit 2aec3bc

Browse files
jonathantanmygitster
authored andcommitted
fetch-pack: do not mix --pack_header and packfile uri
When fetching (as opposed to cloning) from a repository with packfile URIs enabled, an error like this may occur: fatal: pack has bad object at offset 12: unknown object type 5 fatal: finish_http_pack_request gave result -1 fatal: fetch-pack: expected keep then TAB at start of http-fetch output This bug was introduced in b664e9f ("fetch-pack: with packfile URIs, use index-pack arg", 2021-02-22), when the index-pack args used when processing the inline packfile of a fetch response and when processing packfile URIs were unified. This bug happens because fetch, by default, partially reads (and consumes) the header of the inline packfile to determine if it should store the downloaded objects as a packfile or loose objects, and thus passes --pack_header=<...> to index-pack to inform it that some bytes are missing. However, when it subsequently fetches the additional packfiles linked by URIs, it reuses the same index-pack arguments, thus wrongly passing --index-pack-arg=--pack_header=<...> when no bytes are missing. This does not happen when cloning because "git clone" always passes do_keep, which instructs the fetch mechanism to always retain the packfile, eliminating the need to read the header. There are a few ways to fix this, including filtering out pack_header arguments when downloading the additional packfiles, but I decided to stick to always using index-pack throughout when packfile URIs are present - thus, Git no longer needs to read the bytes, and no longer needs --pack_header here. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5476e1e commit 2aec3bc

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

fetch-pack.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ static int get_pack(struct fetch_pack_args *args,
852852
else
853853
demux.out = xd[0];
854854

855-
if (!args->keep_pack && unpack_limit) {
855+
if (!args->keep_pack && unpack_limit && !index_pack_args) {
856856

857857
if (read_pack_header(demux.out, &header))
858858
die(_("protocol error: bad pack header"));
@@ -885,7 +885,7 @@ static int get_pack(struct fetch_pack_args *args,
885885
strvec_push(&cmd.args, "-v");
886886
if (args->use_thin_pack)
887887
strvec_push(&cmd.args, "--fix-thin");
888-
if (do_keep && (args->lock_pack || unpack_limit)) {
888+
if ((do_keep || index_pack_args) && (args->lock_pack || unpack_limit)) {
889889
char hostname[HOST_NAME_MAX + 1];
890890
if (xgethostname(hostname, sizeof(hostname)))
891891
xsnprintf(hostname, sizeof(hostname), "localhost");

t/t5702-protocol-v2.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,27 @@ test_expect_success 'part of packfile response provided as URI' '
853853
test_line_count = 6 filelist
854854
'
855855

856+
test_expect_success 'packfile URIs with fetch instead of clone' '
857+
P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
858+
rm -rf "$P" http_child log &&
859+
860+
git init "$P" &&
861+
git -C "$P" config "uploadpack.allowsidebandall" "true" &&
862+
863+
echo my-blob >"$P/my-blob" &&
864+
git -C "$P" add my-blob &&
865+
git -C "$P" commit -m x &&
866+
867+
configure_exclusion "$P" my-blob >h &&
868+
869+
git init http_child &&
870+
871+
GIT_TEST_SIDEBAND_ALL=1 \
872+
git -C http_child -c protocol.version=2 \
873+
-c fetch.uriprotocols=http,https \
874+
fetch "$HTTPD_URL/smart/http_parent"
875+
'
876+
856877
test_expect_success 'fetching with valid packfile URI but invalid hash fails' '
857878
P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
858879
rm -rf "$P" http_child log &&

0 commit comments

Comments
 (0)