@@ -787,13 +787,13 @@ static void prime_ref_dir(struct ref_dir *dir)
787
787
}
788
788
}
789
789
790
- static int entry_matches (struct ref_entry * entry , const char * refname )
790
+ static int entry_matches (struct ref_entry * entry , const struct string_list * list )
791
791
{
792
- return refname && ! strcmp ( entry -> name , refname );
792
+ return list && string_list_has_string ( list , entry -> name );
793
793
}
794
794
795
795
struct nonmatching_ref_data {
796
- const char * skip ;
796
+ const struct string_list * skip ;
797
797
struct ref_entry * found ;
798
798
};
799
799
@@ -817,16 +817,19 @@ static void report_refname_conflict(struct ref_entry *entry,
817
817
/*
818
818
* Return true iff a reference named refname could be created without
819
819
* conflicting with the name of an existing reference in dir. If
820
- * oldrefname is non-NULL, ignore potential conflicts with oldrefname
821
- * (e.g., because oldrefname is scheduled for deletion in the same
820
+ * skip is non-NULL, ignore potential conflicts with refs in skip
821
+ * (e.g., because they are scheduled for deletion in the same
822
822
* operation).
823
823
*
824
824
* Two reference names conflict if one of them exactly matches the
825
825
* leading components of the other; e.g., "foo/bar" conflicts with
826
826
* both "foo" and with "foo/bar/baz" but not with "foo/bar" or
827
827
* "foo/barbados".
828
+ *
829
+ * skip must be sorted.
828
830
*/
829
- static int is_refname_available (const char * refname , const char * oldrefname ,
831
+ static int is_refname_available (const char * refname ,
832
+ const struct string_list * skip ,
830
833
struct ref_dir * dir )
831
834
{
832
835
const char * slash ;
@@ -840,12 +843,12 @@ static int is_refname_available(const char *refname, const char *oldrefname,
840
843
* looking for a conflict with a leaf entry.
841
844
*
842
845
* If we find one, we still must make sure it is
843
- * not "oldrefname ".
846
+ * not in "skip ".
844
847
*/
845
848
pos = search_ref_dir (dir , refname , slash - refname );
846
849
if (pos >= 0 ) {
847
850
struct ref_entry * entry = dir -> entries [pos ];
848
- if (entry_matches (entry , oldrefname ))
851
+ if (entry_matches (entry , skip ))
849
852
return 1 ;
850
853
report_refname_conflict (entry , refname );
851
854
return 0 ;
@@ -878,13 +881,13 @@ static int is_refname_available(const char *refname, const char *oldrefname,
878
881
/*
879
882
* We found a directory named "refname". It is a
880
883
* problem iff it contains any ref that is not
881
- * "oldrefname ".
884
+ * in "skip ".
882
885
*/
883
886
struct ref_entry * entry = dir -> entries [pos ];
884
887
struct ref_dir * dir = get_ref_dir (entry );
885
888
struct nonmatching_ref_data data ;
886
889
887
- data .skip = oldrefname ;
890
+ data .skip = skip ;
888
891
sort_ref_dir (dir );
889
892
if (!do_for_each_entry_in_dir (dir , 0 , nonmatching_ref_fn , & data ))
890
893
return 1 ;
@@ -2139,6 +2142,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
2139
2142
*/
2140
2143
static struct ref_lock * lock_ref_sha1_basic (const char * refname ,
2141
2144
const unsigned char * old_sha1 ,
2145
+ const struct string_list * skip ,
2142
2146
int flags , int * type_p )
2143
2147
{
2144
2148
char * ref_file ;
@@ -2188,7 +2192,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
2188
2192
* name is a proper prefix of our refname.
2189
2193
*/
2190
2194
if (missing &&
2191
- !is_refname_available (refname , NULL , get_packed_refs (& ref_cache ))) {
2195
+ !is_refname_available (refname , skip , get_packed_refs (& ref_cache ))) {
2192
2196
last_errno = ENOTDIR ;
2193
2197
goto error_return ;
2194
2198
}
@@ -2246,7 +2250,7 @@ struct ref_lock *lock_any_ref_for_update(const char *refname,
2246
2250
const unsigned char * old_sha1 ,
2247
2251
int flags , int * type_p )
2248
2252
{
2249
- return lock_ref_sha1_basic (refname , old_sha1 , flags , type_p );
2253
+ return lock_ref_sha1_basic (refname , old_sha1 , NULL , flags , type_p );
2250
2254
}
2251
2255
2252
2256
/*
@@ -2690,6 +2694,18 @@ static int rename_tmp_log(const char *newrefname)
2690
2694
return 0 ;
2691
2695
}
2692
2696
2697
+ static int rename_ref_available (const char * oldname , const char * newname )
2698
+ {
2699
+ struct string_list skip = STRING_LIST_INIT_NODUP ;
2700
+ int ret ;
2701
+
2702
+ string_list_insert (& skip , oldname );
2703
+ ret = is_refname_available (newname , & skip , get_packed_refs (& ref_cache ))
2704
+ && is_refname_available (newname , & skip , get_loose_refs (& ref_cache ));
2705
+ string_list_clear (& skip , 0 );
2706
+ return ret ;
2707
+ }
2708
+
2693
2709
int rename_ref (const char * oldrefname , const char * newrefname , const char * logmsg )
2694
2710
{
2695
2711
unsigned char sha1 [20 ], orig_sha1 [20 ];
@@ -2709,10 +2725,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
2709
2725
if (!symref )
2710
2726
return error ("refname %s not found" , oldrefname );
2711
2727
2712
- if (!is_refname_available (newrefname , oldrefname , get_packed_refs (& ref_cache )))
2713
- return 1 ;
2714
-
2715
- if (!is_refname_available (newrefname , oldrefname , get_loose_refs (& ref_cache )))
2728
+ if (!rename_ref_available (oldrefname , newrefname ))
2716
2729
return 1 ;
2717
2730
2718
2731
if (log && rename (git_path ("logs/%s" , oldrefname ), git_path (TMP_RENAMED_LOG )))
@@ -2742,7 +2755,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
2742
2755
2743
2756
logmoved = log ;
2744
2757
2745
- lock = lock_ref_sha1_basic (newrefname , NULL , 0 , NULL );
2758
+ lock = lock_ref_sha1_basic (newrefname , NULL , NULL , 0 , NULL );
2746
2759
if (!lock ) {
2747
2760
error ("unable to lock %s for update" , newrefname );
2748
2761
goto rollback ;
@@ -2757,7 +2770,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
2757
2770
return 0 ;
2758
2771
2759
2772
rollback :
2760
- lock = lock_ref_sha1_basic (oldrefname , NULL , 0 , NULL );
2773
+ lock = lock_ref_sha1_basic (oldrefname , NULL , NULL , 0 , NULL );
2761
2774
if (!lock ) {
2762
2775
error ("unable to lock %s for rollback" , oldrefname );
2763
2776
goto rollbacklog ;
@@ -3636,6 +3649,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3636
3649
(update -> have_old ?
3637
3650
update -> old_sha1 :
3638
3651
NULL ),
3652
+ NULL ,
3639
3653
update -> flags ,
3640
3654
& update -> type );
3641
3655
if (!update -> lock ) {
0 commit comments