aboutsummaryrefslogtreecommitdiffstats
path: root/refs.c
diff options
context:
space:
mode:
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/refs.c b/refs.c
index 03fa238d96..957446da9e 100644
--- a/refs.c
+++ b/refs.c
@@ -2485,6 +2485,7 @@ int refs_verify_refnames_available(struct ref_store *refs,
struct strbuf dirname = STRBUF_INIT;
struct strbuf referent = STRBUF_INIT;
struct string_list_item *item;
+ struct strset dirnames;
int ret = -1;
/*
@@ -2494,6 +2495,8 @@ int refs_verify_refnames_available(struct ref_store *refs,
assert(err);
+ strset_init(&dirnames);
+
for_each_string_list_item(item, refnames) {
const char *refname = item->string;
const char *extra_refname;
@@ -2523,6 +2526,14 @@ int refs_verify_refnames_available(struct ref_store *refs,
if (skip && string_list_has_string(skip, dirname.buf))
continue;
+ /*
+ * If we've already seen the directory we don't need to
+ * process it again. Skip it to avoid checking checking
+ * common prefixes like "refs/heads/" repeatedly.
+ */
+ if (!strset_add(&dirnames, dirname.buf))
+ continue;
+
if (!initial_transaction &&
!refs_read_raw_ref(refs, dirname.buf, &oid, &referent,
&type, &ignore_errno)) {
@@ -2583,6 +2594,7 @@ int refs_verify_refnames_available(struct ref_store *refs,
cleanup:
strbuf_release(&referent);
strbuf_release(&dirname);
+ strset_clear(&dirnames);
return ret;
}