summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5cc3cef)
raw | patch | inline | side by side (parent: 5cc3cef)
author | Junio C Hamano <junkio@cox.net> | |
Sat, 30 Sep 2006 21:19:25 +0000 (14:19 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Sat, 30 Sep 2006 22:07:58 +0000 (15:07 -0700) |
This makes the ref locking codepath to notice if an existing ref
overlaps with the ref we are creating.
Signed-off-by: Junio C Hamano <junkio@cox.net>
overlaps with the ref we are creating.
Signed-off-by: Junio C Hamano <junkio@cox.net>
refs.c | patch | blob | history |
index 157de432ced603cd27f6c181195fa8f72a023c8f..2bfa92a8a3af861cbe5937dfb64a19b6d4a7069c 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -588,6 +588,30 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
orig_ref, strerror(errno));
goto error_return;
}
+ if (is_null_sha1(lock->old_sha1)) {
+ /* The ref did not exist and we are creating it.
+ * Make sure there is no existing ref that is packed
+ * whose name begins with our refname, nor a ref whose
+ * name is a proper prefix of our refname.
+ */
+ int namlen = strlen(ref); /* e.g. 'foo/bar' */
+ struct ref_list *list = get_packed_refs();
+ while (list) {
+ /* list->name could be 'foo' or 'foo/bar/baz' */
+ int len = strlen(list->name);
+ int cmplen = (namlen < len) ? namlen : len;
+ const char *lead = (namlen < len) ? list->name : ref;
+
+ if (!strncmp(ref, list->name, cmplen) &&
+ lead[cmplen] == '/') {
+ error("'%s' exists; cannot create '%s'",
+ list->name, ref);
+ goto error_return;
+ }
+ list = list->next;
+ }
+ }
+
lock->lk = xcalloc(1, sizeof(struct lock_file));
lock->ref_name = xstrdup(ref);