787
}
788
}
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
{
792
- return refname && !strcmp(entry->name, refname);
792
+ return list && string_list_has_string(list, entry->name);
793
}
794
795
struct nonmatching_ref_data {
796
- const char *skip;
796
+ const struct string_list *skip;
797
struct ref_entry *found;
798
};
799
817
/*
818
* Return true iff a reference named refname could be created without
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
* operation).
823
*
824
* Two reference names conflict if one of them exactly matches the
825
* leading components of the other; e.g., "foo/bar" conflicts with
826
* both "foo" and with "foo/bar/baz" but not with "foo/bar" or
827
* "foo/barbados".
828
+ *
829
+ * skip must be sorted.
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,
833
struct ref_dir *dir)
834
{
835
const char *slash;
843
* looking for a conflict with a leaf entry.
844
*
845
* If we find one, we still must make sure it is
843
- * not "oldrefname".
846
+ * not in "skip".
847
*/
848
pos = search_ref_dir(dir, refname, slash - refname);
849
if (pos >= 0) {
850
struct ref_entry *entry = dir->entries[pos];
848
- if (entry_matches(entry, oldrefname))
851
+ if (entry_matches(entry, skip))
852
return 1;
853
report_refname_conflict(entry, refname);
854
return 0;
881
/*
882
* We found a directory named "refname". It is a
883
* problem iff it contains any ref that is not
881
- * "oldrefname".
884
+ * in "skip".
885
*/
886
struct ref_entry *entry = dir->entries[pos];
887
struct ref_dir *dir = get_ref_dir(entry);
888
struct nonmatching_ref_data data;
889
887
- data.skip = oldrefname;
890
+ data.skip = skip;
891
sort_ref_dir(dir);
892
if (!do_for_each_entry_in_dir(dir, 0, nonmatching_ref_fn, &data))
893
return 1;
2142
*/
2143
static struct ref_lock *lock_ref_sha1_basic(const char *refname,
2144
const unsigned char *old_sha1,
2145
+ const struct string_list *skip,
2146
int flags, int *type_p)
2147
{
2148
char *ref_file;
2192
* name is a proper prefix of our refname.
2193
*/
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))) {
2196
last_errno = ENOTDIR;
2197
goto error_return;
2198
}
2250
const unsigned char *old_sha1,
2251
int flags, int *type_p)
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);
2254
}
2255
2256
/*
2694
return 0;
2695
}
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
+
2709
int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg)
2710
{
2711
unsigned char sha1[20], orig_sha1[20];
2725
if (!symref)
2726
return error("refname %s not found", oldrefname);
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))
2729
return 1;
2730
2731
if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG)))
2755
2756
logmoved = log;
2757
2745
- lock = lock_ref_sha1_basic(newrefname, NULL, 0, NULL);
2758
+ lock = lock_ref_sha1_basic(newrefname, NULL, NULL, 0, NULL);
2759
if (!lock) {
2760
error("unable to lock %s for update", newrefname);
2761
goto rollback;
2770
return 0;
2771
2772
rollback:
2760
- lock = lock_ref_sha1_basic(oldrefname, NULL, 0, NULL);
2773
+ lock = lock_ref_sha1_basic(oldrefname, NULL, NULL, 0, NULL);
2774
if (!lock) {
2775
error("unable to lock %s for rollback", oldrefname);
2776
goto rollbacklog;
3649
(update->have_old ?
3650
update->old_sha1 :
3651
NULL),
3652
+ NULL,
3653
update->flags,
3654
&update->type);
3655
if (!update->lock) {