@@ -38,6 +38,7 @@ static struct lock_file shallow_lock;
38
38
static const char * alternate_shallow_file ;
39
39
static char * negotiation_algorithm ;
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)
@@ -755,7 +756,8 @@ static int sideband_demux(int in, int out, void *data)
755
756
}
756
757
757
758
static int get_pack (struct fetch_pack_args * args ,
758
- int xd [2 ], struct string_list * pack_lockfiles )
759
+ int xd [2 ], struct string_list * pack_lockfiles ,
760
+ int only_packfile )
759
761
{
760
762
struct async demux ;
761
763
int do_keep = args -> keep_pack ;
@@ -815,8 +817,15 @@ static int get_pack(struct fetch_pack_args *args,
815
817
"--keep=fetch-pack %" PRIuMAX " on %s" ,
816
818
(uintmax_t )getpid (), hostname );
817
819
}
818
- if (args -> check_self_contained_and_connected )
820
+ if (only_packfile && args -> check_self_contained_and_connected )
819
821
argv_array_push (& cmd .args , "--check-self-contained-and-connected" );
822
+ else
823
+ /*
824
+ * We cannot perform any connectivity checks because
825
+ * not all packs have been downloaded; let the caller
826
+ * have this responsibility.
827
+ */
828
+ args -> check_self_contained_and_connected = 0 ;
820
829
if (args -> from_promisor )
821
830
argv_array_push (& cmd .args , "--promisor" );
822
831
}
@@ -993,7 +1002,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
993
1002
alternate_shallow_file = setup_temporary_shallow (si -> shallow );
994
1003
else
995
1004
alternate_shallow_file = NULL ;
996
- if (get_pack (args , fd , pack_lockfiles ))
1005
+ if (get_pack (args , fd , pack_lockfiles , 1 ))
997
1006
die (_ ("git fetch-pack: fetch failed." ));
998
1007
999
1008
all_done :
@@ -1148,6 +1157,26 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
1148
1157
warning ("filtering not recognized by server, ignoring" );
1149
1158
}
1150
1159
1160
+ if (server_supports_feature ("fetch" , "packfile-uris" , 0 )) {
1161
+ int i ;
1162
+ struct strbuf to_send = STRBUF_INIT ;
1163
+
1164
+ for (i = 0 ; i < uri_protocols .nr ; i ++ ) {
1165
+ const char * s = uri_protocols .items [i ].string ;
1166
+
1167
+ if (!strcmp (s , "https" ) || !strcmp (s , "http" )) {
1168
+ if (to_send .len )
1169
+ strbuf_addch (& to_send , ',' );
1170
+ strbuf_addstr (& to_send , s );
1171
+ }
1172
+ }
1173
+ if (to_send .len ) {
1174
+ packet_buf_write (& req_buf , "packfile-uris %s" ,
1175
+ to_send .buf );
1176
+ strbuf_release (& to_send );
1177
+ }
1178
+ }
1179
+
1151
1180
/* add wants */
1152
1181
add_wants (args -> no_dependents , wants , & req_buf );
1153
1182
@@ -1323,6 +1352,21 @@ static void receive_wanted_refs(struct packet_reader *reader,
1323
1352
die (_ ("error processing wanted refs: %d" ), reader -> status );
1324
1353
}
1325
1354
1355
+ static void receive_packfile_uris (struct packet_reader * reader ,
1356
+ struct string_list * uris )
1357
+ {
1358
+ process_section_header (reader , "packfile-uris" , 0 );
1359
+ while (packet_reader_read (reader ) == PACKET_READ_NORMAL ) {
1360
+ if (reader -> pktlen < the_hash_algo -> hexsz ||
1361
+ reader -> line [the_hash_algo -> hexsz ] != ' ' )
1362
+ die ("expected '<hash> <uri>', got: %s\n" , reader -> line );
1363
+
1364
+ string_list_append (uris , reader -> line );
1365
+ }
1366
+ if (reader -> status != PACKET_READ_DELIM )
1367
+ die ("expected DELIM" );
1368
+ }
1369
+
1326
1370
enum fetch_state {
1327
1371
FETCH_CHECK_LOCAL = 0 ,
1328
1372
FETCH_SEND_REQUEST ,
@@ -1344,6 +1388,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1344
1388
int in_vain = 0 ;
1345
1389
int haves_to_send = INITIAL_FLUSH ;
1346
1390
struct fetch_negotiator negotiator ;
1391
+ struct string_list packfile_uris = STRING_LIST_INIT_DUP ;
1392
+ int i ;
1393
+
1347
1394
fetch_negotiator_init (& negotiator , negotiation_algorithm );
1348
1395
packet_reader_init (& reader , fd [0 ], NULL , 0 ,
1349
1396
PACKET_READ_CHOMP_NEWLINE |
@@ -1414,9 +1461,12 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1414
1461
if (process_section_header (& reader , "wanted-refs" , 1 ))
1415
1462
receive_wanted_refs (& reader , sought , nr_sought );
1416
1463
1417
- /* get the pack */
1464
+ /* get the pack(s) */
1465
+ if (process_section_header (& reader , "packfile-uris" , 1 ))
1466
+ receive_packfile_uris (& reader , & packfile_uris );
1418
1467
process_section_header (& reader , "packfile" , 0 );
1419
- if (get_pack (args , fd , pack_lockfiles ))
1468
+ if (get_pack (args , fd , pack_lockfiles ,
1469
+ !packfile_uris .nr ))
1420
1470
die (_ ("git fetch-pack: fetch failed." ));
1421
1471
1422
1472
state = FETCH_DONE ;
@@ -1426,6 +1476,50 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1426
1476
}
1427
1477
}
1428
1478
1479
+ for (i = 0 ; i < packfile_uris .nr ; i ++ ) {
1480
+ struct child_process cmd = CHILD_PROCESS_INIT ;
1481
+ char packname [GIT_MAX_HEXSZ + 1 ];
1482
+ const char * uri = packfile_uris .items [i ].string +
1483
+ the_hash_algo -> hexsz + 1 ;
1484
+
1485
+ argv_array_push (& cmd .args , "http-fetch" );
1486
+ argv_array_push (& cmd .args , "--packfile" );
1487
+ argv_array_push (& cmd .args , uri );
1488
+ cmd .git_cmd = 1 ;
1489
+ cmd .no_stdin = 1 ;
1490
+ cmd .out = -1 ;
1491
+ if (start_command (& cmd ))
1492
+ die ("fetch-pack: unable to spawn http-fetch" );
1493
+
1494
+ if (read_in_full (cmd .out , packname , 5 ) < 0 ||
1495
+ memcmp (packname , "keep\t" , 5 ))
1496
+ die ("fetch-pack: expected keep then TAB at start of http-fetch output" );
1497
+
1498
+ if (read_in_full (cmd .out , packname ,
1499
+ the_hash_algo -> hexsz + 1 ) < 0 ||
1500
+ packname [the_hash_algo -> hexsz ] != '\n' )
1501
+ die ("fetch-pack: expected hash then LF at end of http-fetch output" );
1502
+
1503
+ packname [the_hash_algo -> hexsz ] = '\0' ;
1504
+
1505
+ close (cmd .out );
1506
+
1507
+ if (finish_command (& cmd ))
1508
+ die ("fetch-pack: unable to finish http-fetch" );
1509
+
1510
+ if (memcmp (packfile_uris .items [i ].string , packname ,
1511
+ the_hash_algo -> hexsz ))
1512
+ die ("fetch-pack: pack downloaded from %s does not match expected hash %.*s" ,
1513
+ uri , (int ) the_hash_algo -> hexsz ,
1514
+ packfile_uris .items [i ].string );
1515
+
1516
+ string_list_append_nodup (pack_lockfiles ,
1517
+ xstrfmt ("%s/pack/pack-%s.keep" ,
1518
+ get_object_directory (),
1519
+ packname ));
1520
+ }
1521
+ string_list_clear (& packfile_uris , 0 );
1522
+
1429
1523
negotiator .release (& negotiator );
1430
1524
oidset_clear (& common );
1431
1525
return ref ;
@@ -1465,6 +1559,14 @@ static void fetch_pack_config(void)
1465
1559
git_config_get_bool ("transfer.fsckobjects" , & transfer_fsck_objects );
1466
1560
git_config_get_string ("fetch.negotiationalgorithm" ,
1467
1561
& negotiation_algorithm );
1562
+ if (!uri_protocols .nr ) {
1563
+ char * str ;
1564
+
1565
+ if (!git_config_get_string ("fetch.uriprotocols" , & str ) && str ) {
1566
+ string_list_split (& uri_protocols , str , ',' , -1 );
1567
+ free (str );
1568
+ }
1569
+ }
1468
1570
1469
1571
git_config (fetch_pack_config_cb , NULL );
1470
1572
}
0 commit comments