summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/refs.c b/refs.c
index 157de43..2bfa92a 100644
--- 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);