@@ -2475,19 +2475,16 @@ int ref_transaction_commit(struct ref_transaction *transaction,
24752475 return ret ;
24762476}
24772477
2478- int refs_verify_refname_available (struct ref_store * refs ,
2479- const char * refname ,
2480- const struct string_list * extras ,
2481- const struct string_list * skip ,
2482- unsigned int initial_transaction ,
2483- struct strbuf * err )
2478+ int refs_verify_refnames_available (struct ref_store * refs ,
2479+ const struct string_list * refnames ,
2480+ const struct string_list * extras ,
2481+ const struct string_list * skip ,
2482+ unsigned int initial_transaction ,
2483+ struct strbuf * err )
24842484{
2485- const char * slash ;
2486- const char * extra_refname ;
24872485 struct strbuf dirname = STRBUF_INIT ;
24882486 struct strbuf referent = STRBUF_INIT ;
2489- struct object_id oid ;
2490- unsigned int type ;
2487+ struct string_list_item * item ;
24912488 int ret = -1 ;
24922489
24932490 /*
@@ -2497,86 +2494,115 @@ int refs_verify_refname_available(struct ref_store *refs,
24972494
24982495 assert (err );
24992496
2500- strbuf_grow (& dirname , strlen (refname ) + 1 );
2501- for (slash = strchr (refname , '/' ); slash ; slash = strchr (slash + 1 , '/' )) {
2502- /*
2503- * Just saying "Is a directory" when we e.g. can't
2504- * lock some multi-level ref isn't very informative,
2505- * the user won't be told *what* is a directory, so
2506- * let's not use strerror() below.
2507- */
2508- int ignore_errno ;
2509- /* Expand dirname to the new prefix, not including the trailing slash: */
2510- strbuf_add (& dirname , refname + dirname .len , slash - refname - dirname .len );
2497+ for_each_string_list_item (item , refnames ) {
2498+ const char * refname = item -> string ;
2499+ const char * extra_refname ;
2500+ struct object_id oid ;
2501+ unsigned int type ;
2502+ const char * slash ;
2503+
2504+ strbuf_reset (& dirname );
2505+
2506+ for (slash = strchr (refname , '/' ); slash ; slash = strchr (slash + 1 , '/' )) {
2507+ /*
2508+ * Just saying "Is a directory" when we e.g. can't
2509+ * lock some multi-level ref isn't very informative,
2510+ * the user won't be told *what* is a directory, so
2511+ * let's not use strerror() below.
2512+ */
2513+ int ignore_errno ;
2514+
2515+ /* Expand dirname to the new prefix, not including the trailing slash: */
2516+ strbuf_add (& dirname , refname + dirname .len , slash - refname - dirname .len );
2517+
2518+ /*
2519+ * We are still at a leading dir of the refname (e.g.,
2520+ * "refs/foo"; if there is a reference with that name,
2521+ * it is a conflict, *unless* it is in skip.
2522+ */
2523+ if (skip && string_list_has_string (skip , dirname .buf ))
2524+ continue ;
2525+
2526+ if (!initial_transaction &&
2527+ !refs_read_raw_ref (refs , dirname .buf , & oid , & referent ,
2528+ & type , & ignore_errno )) {
2529+ strbuf_addf (err , _ ("'%s' exists; cannot create '%s'" ),
2530+ dirname .buf , refname );
2531+ goto cleanup ;
2532+ }
2533+
2534+ if (extras && string_list_has_string (extras , dirname .buf )) {
2535+ strbuf_addf (err , _ ("cannot process '%s' and '%s' at the same time" ),
2536+ refname , dirname .buf );
2537+ goto cleanup ;
2538+ }
2539+ }
25112540
25122541 /*
2513- * We are still at a leading dir of the refname (e.g.,
2514- * "refs/foo"; if there is a reference with that name,
2515- * it is a conflict, *unless* it is in skip.
2542+ * We are at the leaf of our refname (e.g., "refs/foo/bar").
2543+ * There is no point in searching for a reference with that
2544+ * name, because a refname isn't considered to conflict with
2545+ * itself. But we still need to check for references whose
2546+ * names are in the "refs/foo/bar/" namespace, because they
2547+ * *do* conflict.
25162548 */
2517- if (skip && string_list_has_string (skip , dirname .buf ))
2518- continue ;
2549+ strbuf_addstr (& dirname , refname + dirname .len );
2550+ strbuf_addch (& dirname , '/' );
2551+
2552+ if (!initial_transaction ) {
2553+ struct ref_iterator * iter ;
2554+ int ok ;
2555+
2556+ iter = refs_ref_iterator_begin (refs , dirname .buf , NULL , 0 ,
2557+ DO_FOR_EACH_INCLUDE_BROKEN );
2558+ while ((ok = ref_iterator_advance (iter )) == ITER_OK ) {
2559+ if (skip &&
2560+ string_list_has_string (skip , iter -> refname ))
2561+ continue ;
2562+
2563+ strbuf_addf (err , _ ("'%s' exists; cannot create '%s'" ),
2564+ iter -> refname , refname );
2565+ ref_iterator_abort (iter );
2566+ goto cleanup ;
2567+ }
25192568
2520- if (!initial_transaction &&
2521- !refs_read_raw_ref (refs , dirname .buf , & oid , & referent ,
2522- & type , & ignore_errno )) {
2523- strbuf_addf (err , _ ("'%s' exists; cannot create '%s'" ),
2524- dirname .buf , refname );
2525- goto cleanup ;
2569+ if (ok != ITER_DONE )
2570+ BUG ("error while iterating over references" );
25262571 }
25272572
2528- if (extras && string_list_has_string (extras , dirname .buf )) {
2573+ extra_refname = find_descendant_ref (dirname .buf , extras , skip );
2574+ if (extra_refname ) {
25292575 strbuf_addf (err , _ ("cannot process '%s' and '%s' at the same time" ),
2530- refname , dirname . buf );
2576+ refname , extra_refname );
25312577 goto cleanup ;
25322578 }
25332579 }
25342580
2535- /*
2536- * We are at the leaf of our refname (e.g., "refs/foo/bar").
2537- * There is no point in searching for a reference with that
2538- * name, because a refname isn't considered to conflict with
2539- * itself. But we still need to check for references whose
2540- * names are in the "refs/foo/bar/" namespace, because they
2541- * *do* conflict.
2542- */
2543- strbuf_addstr (& dirname , refname + dirname .len );
2544- strbuf_addch (& dirname , '/' );
2545-
2546- if (!initial_transaction ) {
2547- struct ref_iterator * iter ;
2548- int ok ;
2549-
2550- iter = refs_ref_iterator_begin (refs , dirname .buf , NULL , 0 ,
2551- DO_FOR_EACH_INCLUDE_BROKEN );
2552- while ((ok = ref_iterator_advance (iter )) == ITER_OK ) {
2553- if (skip &&
2554- string_list_has_string (skip , iter -> refname ))
2555- continue ;
2556-
2557- strbuf_addf (err , _ ("'%s' exists; cannot create '%s'" ),
2558- iter -> refname , refname );
2559- ref_iterator_abort (iter );
2560- goto cleanup ;
2561- }
2562-
2563- if (ok != ITER_DONE )
2564- BUG ("error while iterating over references" );
2565- }
2566-
2567- extra_refname = find_descendant_ref (dirname .buf , extras , skip );
2568- if (extra_refname )
2569- strbuf_addf (err , _ ("cannot process '%s' and '%s' at the same time" ),
2570- refname , extra_refname );
2571- else
2572- ret = 0 ;
2581+ ret = 0 ;
25732582
25742583cleanup :
25752584 strbuf_release (& referent );
25762585 strbuf_release (& dirname );
25772586 return ret ;
25782587}
25792588
2589+ int refs_verify_refname_available (struct ref_store * refs ,
2590+ const char * refname ,
2591+ const struct string_list * extras ,
2592+ const struct string_list * skip ,
2593+ unsigned int initial_transaction ,
2594+ struct strbuf * err )
2595+ {
2596+ struct string_list_item item = { .string = (char * ) refname };
2597+ struct string_list refnames = {
2598+ .items = & item ,
2599+ .nr = 1 ,
2600+ };
2601+
2602+ return refs_verify_refnames_available (refs , & refnames , extras , skip ,
2603+ initial_transaction , err );
2604+ }
2605+
25802606struct do_for_each_reflog_help {
25812607 each_reflog_fn * fn ;
25822608 void * cb_data ;
0 commit comments