Skip to content

Commit 8cb062f

Browse files
tnm-oaigitster
authored andcommitted
fetch-pack: accept "pack" output for packfile URIs
When index-pack finds an existing keep file it reports pack rather than keep. Accept either result from http-fetch, and only register a keep lockfile when this fetch created it. Read the pack/keep prefix and hash without consuming any following fsck output, validate the reported pack hash against the advertised hash, and exercise a packfile URI fetch with a pre-existing keep file. Signed-off-by: Ted Nyman <tnyman@openai.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent d2c25ff commit 8cb062f

2 files changed

Lines changed: 49 additions & 15 deletions

File tree

fetch-pack.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,9 +1887,10 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
18871887
}
18881888

18891889
for (i = 0; i < packfile_uris.nr; i++) {
1890+
bool created_keep;
18901891
int j;
18911892
struct child_process cmd = CHILD_PROCESS_INIT;
1892-
char packname[GIT_MAX_HEXSZ + 1];
1893+
char packhash[GIT_MAX_HEXSZ + 1];
18931894
const char *uri = packfile_uris.items[i].string +
18941895
the_hash_algo->hexsz + 1;
18951896

@@ -1907,16 +1908,17 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
19071908
if (start_command(&cmd))
19081909
die("fetch-pack: unable to spawn http-fetch");
19091910

1910-
if (read_in_full(cmd.out, packname, 5) < 0 ||
1911-
memcmp(packname, "keep\t", 5))
1912-
die("fetch-pack: expected keep then TAB at start of http-fetch output");
1911+
if (read_in_full(cmd.out, packhash, 5) != 5 ||
1912+
(memcmp(packhash, "keep\t", 5) &&
1913+
memcmp(packhash, "pack\t", 5)))
1914+
die("fetch-pack: expected pack or keep then TAB at start of http-fetch output");
1915+
created_keep = !memcmp(packhash, "keep\t", 5);
19131916

1914-
if (read_in_full(cmd.out, packname,
1915-
the_hash_algo->hexsz + 1) < 0 ||
1916-
packname[the_hash_algo->hexsz] != '\n')
1917-
die("fetch-pack: expected hash then LF at end of http-fetch output");
1918-
1919-
packname[the_hash_algo->hexsz] = '\0';
1917+
if (read_in_full(cmd.out, packhash,
1918+
the_hash_algo->hexsz + 1) != the_hash_algo->hexsz + 1 ||
1919+
packhash[the_hash_algo->hexsz] != '\n')
1920+
die("fetch-pack: expected hash then LF in http-fetch output");
1921+
packhash[the_hash_algo->hexsz] = '\0';
19201922

19211923
parse_gitmodules_oids(cmd.out, &fsck_options.gitmodules_found);
19221924

@@ -1925,16 +1927,17 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
19251927
if (finish_command(&cmd))
19261928
die("fetch-pack: unable to finish http-fetch");
19271929

1928-
if (memcmp(packfile_uris.items[i].string, packname,
1930+
if (memcmp(packfile_uris.items[i].string, packhash,
19291931
the_hash_algo->hexsz))
19301932
die("fetch-pack: pack downloaded from %s does not match expected hash %.*s",
19311933
uri, (int) the_hash_algo->hexsz,
19321934
packfile_uris.items[i].string);
19331935

1934-
string_list_append_nodup(pack_lockfiles,
1935-
xstrfmt("%s/pack/pack-%s.keep",
1936-
repo_get_object_directory(the_repository),
1937-
packname));
1936+
if (created_keep)
1937+
string_list_append_nodup(pack_lockfiles,
1938+
xstrfmt("%s/pack/pack-%s.keep",
1939+
repo_get_object_directory(the_repository),
1940+
packhash));
19381941
}
19391942
string_list_clear(&packfile_uris, 0);
19401943
strvec_clear(&index_pack_args);

t/t5702-protocol-v2.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,37 @@ test_expect_success 'packfile URIs with fetch instead of clone' '
12911291
fetch "$HTTPD_URL/smart/http_parent"
12921292
'
12931293

1294+
test_expect_success 'packfile URI preserves an existing keep file' '
1295+
P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
1296+
rm -rf "$P" http_child keep.expect &&
1297+
1298+
git init "$P" &&
1299+
git -C "$P" config uploadpack.allowsidebandall true &&
1300+
1301+
echo my-blob >"$P/my-blob" &&
1302+
git -C "$P" add my-blob &&
1303+
git -C "$P" commit -m x &&
1304+
configure_exclusion "$P" my-blob >h &&
1305+
1306+
git init http_child &&
1307+
packhash=$(cat packh) &&
1308+
keep="http_child/.git/objects/pack/pack-$packhash.keep" &&
1309+
echo pre-existing >"$keep" &&
1310+
cp "$keep" keep.expect &&
1311+
1312+
GIT_TEST_SIDEBAND_ALL=1 \
1313+
git -C http_child -c protocol.version=2 \
1314+
-c fetch.uriprotocols=http,https \
1315+
fetch "$HTTPD_URL/smart/http_parent" &&
1316+
1317+
test_path_is_file \
1318+
"http_child/.git/objects/pack/pack-$packhash.pack" &&
1319+
test_path_is_file \
1320+
"http_child/.git/objects/pack/pack-$packhash.idx" &&
1321+
test_cmp keep.expect "$keep" &&
1322+
git -C http_child cat-file -e "$(cat h)"
1323+
'
1324+
12941325
test_expect_success 'fetching with valid packfile URI but invalid hash fails' '
12951326
P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
12961327
rm -rf "$P" http_child log &&

0 commit comments

Comments
 (0)