@@ -314,10 +314,37 @@ static int allow_unsanitized(char ch)
314
314
return ch > 32 && ch < 127 ;
315
315
}
316
316
317
- static void promisor_info_vecs (struct repository * repo ,
318
- struct strvec * names ,
319
- struct strvec * urls )
317
+ /*
318
+ * Linked list for promisor remotes involved in the "promisor-remote"
319
+ * protocol capability.
320
+ *
321
+ * Except for "next" and "name", each <member> in this struct and its
322
+ * <value> should correspond to a "remote.<name>.<member>" config
323
+ * variable set to <value> where "<name>" is a promisor remote name.
324
+ */
325
+ struct promisor_info {
326
+ struct promisor_info * next ;
327
+ const char * name ;
328
+ const char * url ;
329
+ };
330
+
331
+ static void promisor_info_list_free (struct promisor_info * p )
332
+ {
333
+ struct promisor_info * next ;
334
+
335
+ for (; p ; p = next ) {
336
+ next = p -> next ;
337
+ free ((char * )p -> name );
338
+ free ((char * )p -> url );
339
+ free (p );
340
+ }
341
+ }
342
+
343
+ /* Prepare a 'struct promisor_info' linked list with config information. */
344
+ static struct promisor_info * promisor_config_info_list (struct repository * repo )
320
345
{
346
+ struct promisor_info * infos = NULL ;
347
+ struct promisor_info * * last_info = & infos ;
321
348
struct promisor_remote * r ;
322
349
323
350
promisor_remote_init (repo );
@@ -328,57 +355,65 @@ static void promisor_info_vecs(struct repository *repo,
328
355
329
356
/* Only add remotes with a non empty URL */
330
357
if (!git_config_get_string_tmp (url_key , & url ) && * url ) {
331
- strvec_push (names , r -> name );
332
- strvec_push (urls , url );
358
+ struct promisor_info * new_info = xcalloc (1 , sizeof (* new_info ));
359
+
360
+ new_info -> name = xstrdup (r -> name );
361
+ new_info -> url = xstrdup (url );
362
+
363
+ * last_info = new_info ;
364
+ last_info = & new_info -> next ;
333
365
}
334
366
335
367
free (url_key );
336
368
}
369
+
370
+ return infos ;
337
371
}
338
372
339
373
char * promisor_remote_info (struct repository * repo )
340
374
{
341
375
struct strbuf sb = STRBUF_INIT ;
342
376
int advertise_promisors = 0 ;
343
- struct strvec names = STRVEC_INIT ;
344
- struct strvec urls = STRVEC_INIT ;
377
+ struct promisor_info * config_info ;
378
+ struct promisor_info * p ;
345
379
346
380
git_config_get_bool ("promisor.advertise" , & advertise_promisors );
347
381
348
382
if (!advertise_promisors )
349
383
return NULL ;
350
384
351
- promisor_info_vecs ( repo , & names , & urls );
385
+ config_info = promisor_config_info_list ( repo );
352
386
353
- if (!names . nr )
387
+ if (!config_info )
354
388
return NULL ;
355
389
356
- for (size_t i = 0 ; i < names . nr ; i ++ ) {
357
- if (i )
390
+ for (p = config_info ; p ; p = p -> next ) {
391
+ if (p != config_info )
358
392
strbuf_addch (& sb , ';' );
393
+
359
394
strbuf_addstr (& sb , "name=" );
360
- strbuf_addstr_urlencode (& sb , names . v [ i ] , allow_unsanitized );
395
+ strbuf_addstr_urlencode (& sb , p -> name , allow_unsanitized );
361
396
strbuf_addstr (& sb , ",url=" );
362
- strbuf_addstr_urlencode (& sb , urls . v [ i ] , allow_unsanitized );
397
+ strbuf_addstr_urlencode (& sb , p -> url , allow_unsanitized );
363
398
}
364
399
365
- strvec_clear (& names );
366
- strvec_clear (& urls );
400
+ promisor_info_list_free (config_info );
367
401
368
402
return strbuf_detach (& sb , NULL );
369
403
}
370
404
371
405
/*
372
- * Find first index of 'nicks ' where there is 'nick'. 'nick' is
373
- * compared case sensitively to the strings in 'nicks '. If not found
374
- * 'nicks->nr' is returned.
406
+ * Find first element of 'p ' where the 'name' member is 'nick'. 'nick'
407
+ * is compared case sensitively to the strings in 'p '. If not found
408
+ * NULL is returned.
375
409
*/
376
- static size_t remote_nick_find (struct strvec * nicks , const char * nick )
410
+ static struct promisor_info * remote_nick_find (struct promisor_info * p , const char * nick )
377
411
{
378
- for (size_t i = 0 ; i < nicks -> nr ; i ++ )
379
- if (!strcmp (nicks -> v [i ], nick ))
380
- return i ;
381
- return nicks -> nr ;
412
+ for (; p ; p = p -> next ) {
413
+ if (!strcmp (p -> name , nick ))
414
+ return p ;
415
+ }
416
+ return NULL ;
382
417
}
383
418
384
419
enum accept_promisor {
@@ -390,16 +425,16 @@ enum accept_promisor {
390
425
391
426
static int should_accept_remote (enum accept_promisor accept ,
392
427
const char * remote_name , const char * remote_url ,
393
- struct strvec * names , struct strvec * urls )
428
+ struct promisor_info * config_info )
394
429
{
395
- size_t i ;
430
+ struct promisor_info * p ;
396
431
397
432
if (accept == ACCEPT_ALL )
398
433
return 1 ;
399
434
400
- i = remote_nick_find (names , remote_name );
435
+ p = remote_nick_find (config_info , remote_name );
401
436
402
- if (i >= names -> nr )
437
+ if (! p )
403
438
/* We don't know about that remote */
404
439
return 0 ;
405
440
@@ -414,11 +449,15 @@ static int should_accept_remote(enum accept_promisor accept,
414
449
return 0 ;
415
450
}
416
451
417
- if (!strcmp (urls -> v [i ], remote_url ))
452
+ if (!p -> url )
453
+ BUG ("Bad config_info (invalid URL) for remote '%s'.\n" ,
454
+ remote_name );
455
+
456
+ if (!strcmp (p -> url , remote_url ))
418
457
return 1 ;
419
458
420
459
warning (_ ("known remote named '%s' but with URL '%s' instead of '%s'" ),
421
- remote_name , urls -> v [ i ] , remote_url );
460
+ remote_name , p -> url , remote_url );
422
461
423
462
return 0 ;
424
463
}
@@ -430,8 +469,7 @@ static void filter_promisor_remote(struct repository *repo,
430
469
struct strbuf * * remotes ;
431
470
const char * accept_str ;
432
471
enum accept_promisor accept = ACCEPT_NONE ;
433
- struct strvec names = STRVEC_INIT ;
434
- struct strvec urls = STRVEC_INIT ;
472
+ struct promisor_info * config_info = NULL ;
435
473
436
474
if (!git_config_get_string_tmp ("promisor.acceptfromserver" , & accept_str )) {
437
475
if (!* accept_str || !strcasecmp ("None" , accept_str ))
@@ -451,7 +489,7 @@ static void filter_promisor_remote(struct repository *repo,
451
489
return ;
452
490
453
491
if (accept != ACCEPT_ALL )
454
- promisor_info_vecs ( repo , & names , & urls );
492
+ config_info = promisor_config_info_list ( repo );
455
493
456
494
/* Parse remote info received */
457
495
@@ -482,16 +520,15 @@ static void filter_promisor_remote(struct repository *repo,
482
520
if (remote_url )
483
521
decoded_url = url_percent_decode (remote_url );
484
522
485
- if (decoded_name && should_accept_remote (accept , decoded_name , decoded_url , & names , & urls ))
523
+ if (decoded_name && should_accept_remote (accept , decoded_name , decoded_url , config_info ))
486
524
strvec_push (accepted , decoded_name );
487
525
488
526
strbuf_list_free (elems );
489
527
free (decoded_name );
490
528
free (decoded_url );
491
529
}
492
530
493
- strvec_clear (& names );
494
- strvec_clear (& urls );
531
+ promisor_info_list_free (config_info );
495
532
strbuf_list_free (remotes );
496
533
}
497
534
0 commit comments