779
prime_ref_dir(get_ref_dir(entry));
780
}
781
}
782
-/*
783
- * Return true iff refname1 and refname2 conflict with each other.
784
- * Two reference names conflict if one of them exactly matches the
785
- * leading components of the other; e.g., "foo/bar" conflicts with
786
- * both "foo" and with "foo/bar/baz" but not with "foo/bar" or
787
- * "foo/barbados".
788
- */
789
-static int names_conflict(const char *refname1, const char *refname2)
782
+
783
+static int entry_matches(struct ref_entry *entry, const char *refname)
784
{
791
- for (; *refname1 && *refname1 == *refname2; refname1++, refname2++)
792
- ;
793
- return (*refname1 == '\0' && *refname2 == '/')
794
- || (*refname1 == '/' && *refname2 == '\0');
785
+ return refname && !strcmp(entry->name, refname);
786
}
787
797
-struct name_conflict_cb {
798
- const char *refname;
799
- const char *oldrefname;
800
- const char *conflicting_refname;
788
+struct nonmatching_ref_data {
789
+ const char *skip;
790
+ struct ref_entry *found;
791
};
792
803
-static int name_conflict_fn(struct ref_entry *entry, void *cb_data)
793
+static int nonmatching_ref_fn(struct ref_entry *entry, void *vdata)
794
{
805
- struct name_conflict_cb *data = (struct name_conflict_cb *)cb_data;
806
- if (data->oldrefname && !strcmp(data->oldrefname, entry->name))
795
+ struct nonmatching_ref_data *data = vdata;
796
+
797
+ if (entry_matches(entry, data->skip))
798
return 0;
808
- if (names_conflict(data->refname, entry->name)) {
809
- data->conflicting_refname = entry->name;
810
- return 1;
811
- }
812
- return 0;
799
+
800
+ data->found = entry;
801
+ return 1;
802
+}
803
+
804
+static void report_refname_conflict(struct ref_entry *entry,
805
+ const char *refname)
806
+{
807
+ error("'%s' exists; cannot create '%s'", entry->name, refname);
808
}
809
810
/*
813
* oldrefname is non-NULL, ignore potential conflicts with oldrefname
814
* (e.g., because oldrefname is scheduled for deletion in the same
815
* operation).
816
+ *
817
+ * Two reference names conflict if one of them exactly matches the
818
+ * leading components of the other; e.g., "foo/bar" conflicts with
819
+ * both "foo" and with "foo/bar/baz" but not with "foo/bar" or
820
+ * "foo/barbados".
821
*/
822
static int is_refname_available(const char *refname, const char *oldrefname,
823
struct ref_dir *dir)
824
{
825
- struct name_conflict_cb data;
826
- data.refname = refname;
827
- data.oldrefname = oldrefname;
828
- data.conflicting_refname = NULL;
825
+ const char *slash;
826
+ size_t len;
827
+ int pos;
828
+ char *dirname;
829
830
- sort_ref_dir(dir);
831
- if (do_for_each_entry_in_dir(dir, 0, name_conflict_fn, &data)) {
832
- error("'%s' exists; cannot create '%s'",
833
- data.conflicting_refname, refname);
830
+ for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
831
+ /*
832
+ * We are still at a leading dir of the refname; we are
833
+ * looking for a conflict with a leaf entry.
834
+ *
835
+ * If we find one, we still must make sure it is
836
+ * not "oldrefname".
837
+ */
838
+ pos = search_ref_dir(dir, refname, slash - refname);
839
+ if (pos >= 0) {
840
+ struct ref_entry *entry = dir->entries[pos];
841
+ if (entry_matches(entry, oldrefname))
842
+ return 1;
843
+ report_refname_conflict(entry, refname);
844
+ return 0;
845
+ }
846
+
847
+
848
+ /*
849
+ * Otherwise, we can try to continue our search with
850
+ * the next component; if we come up empty, we know
851
+ * there is nothing under this whole prefix.
852
+ */
853
+ pos = search_ref_dir(dir, refname, slash + 1 - refname);
854
+ if (pos < 0)
855
+ return 1;
856
+
857
+ dir = get_ref_dir(dir->entries[pos]);
858
+ }
859
+
860
+ /*
861
+ * We are at the leaf of our refname; we want to
862
+ * make sure there are no directories which match it.
863
+ */
864
+ len = strlen(refname);
865
+ dirname = xmallocz(len + 1);
866
+ sprintf(dirname, "%s/", refname);
867
+ pos = search_ref_dir(dir, dirname, len + 1);
868
+ free(dirname);
869
+
870
+ if (pos >= 0) {
871
+ /*
872
+ * We found a directory named "refname". It is a
873
+ * problem iff it contains any ref that is not
874
+ * "oldrefname".
875
+ */
876
+ struct ref_entry *entry = dir->entries[pos];
877
+ struct ref_dir *dir = get_ref_dir(entry);
878
+ struct nonmatching_ref_data data;
879
+
880
+ data.skip = oldrefname;
881
+ sort_ref_dir(dir);
882
+ if (!do_for_each_entry_in_dir(dir, 0, nonmatching_ref_fn, &data))
883
+ return 1;
884
+
885
+ report_refname_conflict(data.found, refname);
886
return 0;
887
}
888
+
889
+ /*
890
+ * There is no point in searching for another leaf
891
+ * node which matches it; such an entry would be the
892
+ * ref we are looking for, not a conflict.
893
+ */
894
return 1;
895
}
896