@@ -38,6 +38,7 @@ static int server_supports_filtering;
38
38
static struct shallow_lock shallow_lock ;
39
39
static const char * alternate_shallow_file ;
40
40
static struct strbuf fsck_msg_types = STRBUF_INIT ;
41
+ static struct string_list uri_protocols = STRING_LIST_INIT_DUP ;
41
42
42
43
/* Remember to update object flag allocation in object.h */
43
44
#define COMPLETE (1U << 0)
@@ -795,6 +796,7 @@ static void write_promisor_file(const char *keep_name,
795
796
796
797
static int get_pack (struct fetch_pack_args * args ,
797
798
int xd [2 ], struct string_list * pack_lockfiles ,
799
+ int only_packfile ,
798
800
struct ref * * sought , int nr_sought )
799
801
{
800
802
struct async demux ;
@@ -855,8 +857,15 @@ static int get_pack(struct fetch_pack_args *args,
855
857
"--keep=fetch-pack %" PRIuMAX " on %s" ,
856
858
(uintmax_t )getpid (), hostname );
857
859
}
858
- if (args -> check_self_contained_and_connected )
860
+ if (only_packfile && args -> check_self_contained_and_connected )
859
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 ;
860
869
/*
861
870
* If we're obtaining the filename of a lockfile, we'll use
862
871
* that filename to write a .promisor file with more
@@ -1068,7 +1077,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1068
1077
alternate_shallow_file = setup_temporary_shallow (si -> shallow );
1069
1078
else
1070
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 ))
1072
1081
die (_ ("git fetch-pack: fetch failed." ));
1073
1082
1074
1083
all_done :
@@ -1222,6 +1231,26 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
1222
1231
warning ("filtering not recognized by server, ignoring" );
1223
1232
}
1224
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
+
1225
1254
/* add wants */
1226
1255
add_wants (args -> no_dependents , wants , & req_buf );
1227
1256
@@ -1444,6 +1473,21 @@ static void receive_wanted_refs(struct packet_reader *reader,
1444
1473
die (_ ("error processing wanted refs: %d" ), reader -> status );
1445
1474
}
1446
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
+
1447
1491
enum fetch_state {
1448
1492
FETCH_CHECK_LOCAL = 0 ,
1449
1493
FETCH_SEND_REQUEST ,
@@ -1470,6 +1514,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1470
1514
struct fetch_negotiator negotiator_alloc ;
1471
1515
struct fetch_negotiator * negotiator ;
1472
1516
int seen_ack = 0 ;
1517
+ struct string_list packfile_uris = STRING_LIST_INIT_DUP ;
1518
+ int i ;
1473
1519
1474
1520
if (args -> no_dependents ) {
1475
1521
negotiator = NULL ;
@@ -1558,9 +1604,12 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1558
1604
if (process_section_header (& reader , "wanted-refs" , 1 ))
1559
1605
receive_wanted_refs (& reader , sought , nr_sought );
1560
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 );
1562
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 ))
1564
1613
die (_ ("git fetch-pack: fetch failed." ));
1565
1614
1566
1615
state = FETCH_DONE ;
@@ -1570,8 +1619,55 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1570
1619
}
1571
1620
}
1572
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
+
1573
1668
if (negotiator )
1574
1669
negotiator -> release (negotiator );
1670
+
1575
1671
oidset_clear (& common );
1576
1672
return ref ;
1577
1673
}
@@ -1608,6 +1704,14 @@ static void fetch_pack_config(void)
1608
1704
git_config_get_bool ("repack.usedeltabaseoffset" , & prefer_ofs_delta );
1609
1705
git_config_get_bool ("fetch.fsckobjects" , & fetch_fsck_objects );
1610
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
+ }
1611
1715
1612
1716
git_config (fetch_pack_config_cb , NULL );
1613
1717
}
0 commit comments