38
static struct shallow_lock shallow_lock;
39
static const char *alternate_shallow_file;
40
static struct strbuf fsck_msg_types = STRBUF_INIT;
41
+static struct string_list uri_protocols = STRING_LIST_INIT_DUP;
42
43
/* Remember to update object flag allocation in object.h */
44
#define COMPLETE (1U << 0)
796
797
static int get_pack(struct fetch_pack_args *args,
798
int xd[2], struct string_list *pack_lockfiles,
799
+ int only_packfile,
800
struct ref **sought, int nr_sought)
801
{
802
struct async demux;
857
"--keep=fetch-pack %"PRIuMAX " on %s",
858
(uintmax_t)getpid(), hostname);
859
}
858
- if (args->check_self_contained_and_connected)
860
+ if (only_packfile && args->check_self_contained_and_connected)
861
argv_array_push(&cmd.args, "--check-self-contained-and-connected");
862
+ else
863
+ /*
864
+ * We cannot perform any connectivity checks because
865
+ * not all packs have been downloaded; let the caller
866
+ * have this responsibility.
867
+ */
868
+ args->check_self_contained_and_connected = 0;
869
/*
870
* If we're obtaining the filename of a lockfile, we'll use
871
* that filename to write a .promisor file with more
1077
alternate_shallow_file = setup_temporary_shallow(si->shallow);
1078
else
1079
alternate_shallow_file = NULL;
1071
- if (get_pack(args, fd, pack_lockfiles, sought, nr_sought))
1080
+ if (get_pack(args, fd, pack_lockfiles, 1, sought, nr_sought))
1081
die(_("git fetch-pack: fetch failed."));
1082
1083
all_done:
1231
warning("filtering not recognized by server, ignoring");
1232
}
1233
1234
+ if (server_supports_feature("fetch", "packfile-uris", 0)) {
1235
+ int i;
1236
+ struct strbuf to_send = STRBUF_INIT;
1237
+
1238
+ for (i = 0; i < uri_protocols.nr; i++) {
1239
+ const char *s = uri_protocols.items[i].string;
1240
+
1241
+ if (!strcmp(s, "https") || !strcmp(s, "http")) {
1242
+ if (to_send.len)
1243
+ strbuf_addch(&to_send, ',');
1244
+ strbuf_addstr(&to_send, s);
1245
+ }
1246
+ }
1247
+ if (to_send.len) {
1248
+ packet_buf_write(&req_buf, "packfile-uris %s",
1249
+ to_send.buf);
1250
+ strbuf_release(&to_send);
1251
+ }
1252
+ }
1253
+
1254
/* add wants */
1255
add_wants(args->no_dependents, wants, &req_buf);
1256
1473
die(_("error processing wanted refs: %d"), reader->status);
1474
}
1475
1476
+static void receive_packfile_uris(struct packet_reader *reader,
1477
+ struct string_list *uris)
1478
+{
1479
+ process_section_header(reader, "packfile-uris", 0);
1480
+ while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
1481
+ if (reader->pktlen < the_hash_algo->hexsz ||
1482
+ reader->line[the_hash_algo->hexsz] != ' ')
1483
+ die("expected '<hash> <uri>', got: %s\n", reader->line);
1484
+
1485
+ string_list_append(uris, reader->line);
1486
+ }
1487
+ if (reader->status != PACKET_READ_DELIM)
1488
+ die("expected DELIM");
1489
+}
1490
+
1491
enum fetch_state {
1492
FETCH_CHECK_LOCAL = 0,
1493
FETCH_SEND_REQUEST,
1514
struct fetch_negotiator negotiator_alloc;
1515
struct fetch_negotiator *negotiator;
1516
int seen_ack = 0;
1517
+ struct string_list packfile_uris = STRING_LIST_INIT_DUP;
1518
+ int i;
1519
1520
if (args->no_dependents) {
1521
negotiator = NULL;
1604
if (process_section_header(&reader, "wanted-refs", 1))
1605
receive_wanted_refs(&reader, sought, nr_sought);
1606
1561
- /* get the pack */
1607
+ /* get the pack(s) */
1608
+ if (process_section_header(&reader, "packfile-uris", 1))
1609
+ receive_packfile_uris(&reader, &packfile_uris);
1610
process_section_header(&reader, "packfile", 0);
1563
- if (get_pack(args, fd, pack_lockfiles, sought, nr_sought))
1611
+ if (get_pack(args, fd, pack_lockfiles,
1612
+ !packfile_uris.nr, sought, nr_sought))
1613
die(_("git fetch-pack: fetch failed."));
1614
1615
state = FETCH_DONE;
1619
}
1620
}
1621
1622
+ for (i = 0; i < packfile_uris.nr; i++) {
1623
+ struct child_process cmd = CHILD_PROCESS_INIT;
1624
+ char packname[GIT_MAX_HEXSZ + 1];
1625
+ const char *uri = packfile_uris.items[i].string +
1626
+ the_hash_algo->hexsz + 1;
1627
+
1628
+ argv_array_push(&cmd.args, "http-fetch");
1629
+ argv_array_pushf(&cmd.args, "--packfile=%.*s",
1630
+ (int) the_hash_algo->hexsz,
1631
+ packfile_uris.items[i].string);
1632
+ argv_array_push(&cmd.args, uri);
1633
+ cmd.git_cmd = 1;
1634
+ cmd.no_stdin = 1;
1635
+ cmd.out = -1;
1636
+ if (start_command(&cmd))
1637
+ die("fetch-pack: unable to spawn http-fetch");
1638
+
1639
+ if (read_in_full(cmd.out, packname, 5) < 0 ||
1640
+ memcmp(packname, "keep\t", 5))
1641
+ die("fetch-pack: expected keep then TAB at start of http-fetch output");
1642
+
1643
+ if (read_in_full(cmd.out, packname,
1644
+ the_hash_algo->hexsz + 1) < 0 ||
1645
+ packname[the_hash_algo->hexsz] != '\n')
1646
+ die("fetch-pack: expected hash then LF at end of http-fetch output");
1647
+
1648
+ packname[the_hash_algo->hexsz] = '\0';
1649
+
1650
+ close(cmd.out);
1651
+
1652
+ if (finish_command(&cmd))
1653
+ die("fetch-pack: unable to finish http-fetch");
1654
+
1655
+ if (memcmp(packfile_uris.items[i].string, packname,
1656
+ the_hash_algo->hexsz))
1657
+ die("fetch-pack: pack downloaded from %s does not match expected hash %.*s",
1658
+ uri, (int) the_hash_algo->hexsz,
1659
+ packfile_uris.items[i].string);
1660
+
1661
+ string_list_append_nodup(pack_lockfiles,
1662
+ xstrfmt("%s/pack/pack-%s.keep",
1663
+ get_object_directory(),
1664
+ packname));
1665
+ }
1666
+ string_list_clear(&packfile_uris, 0);
1667
+
1668
if (negotiator)
1669
negotiator->release(negotiator);
1670
+
1671
oidset_clear(&common);
1672
return ref;
1673
}
1704
git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
1705
git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
1706
git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
1707
+ if (!uri_protocols.nr) {
1708
+ char *str;
1709
+
1710
+ if (!git_config_get_string("fetch.uriprotocols", &str) && str) {
1711
+ string_list_split(&uri_protocols, str, ',', -1);
1712
+ free(str);
1713
+ }
1714
+ }
1715
1716
git_config(fetch_pack_config_cb, NULL);
1717
}