diff --git a/refs/files-backend.c b/refs/files-backend.c index 88f8c7aa4b..bce0022345 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2280,10 +2280,18 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data) return 0; } +enum { + REMOVE_EMPTY_PARENTS_REF = 0x01, + REMOVE_EMPTY_PARENTS_REFLOG = 0x02 +}; + /* - * Remove empty parents, but spare refs/ and immediate subdirs. + * Remove empty parent directories associated with the specified + * reference and/or its reflog, but spare [logs/]refs/ and immediate + * subdirs. flags is a combination of REMOVE_EMPTY_PARENTS_REF and/or + * REMOVE_EMPTY_PARENTS_REFLOG. */ -static void try_remove_empty_parents(const char *refname) +static void try_remove_empty_parents(const char *refname, unsigned int flags) { struct strbuf buf = STRBUF_INIT; char *p, *q; @@ -2299,7 +2307,7 @@ static void try_remove_empty_parents(const char *refname) p++; } q = buf.buf + buf.len; - while (1) { + while (flags & (REMOVE_EMPTY_PARENTS_REF | REMOVE_EMPTY_PARENTS_REFLOG)) { while (q > p && *q != '/') q--; while (q > p && *(q-1) == '/') @@ -2307,8 +2315,12 @@ static void try_remove_empty_parents(const char *refname) if (q == p) break; strbuf_setlen(&buf, q - buf.buf); - if (rmdir(git_path("%s", buf.buf))) - break; + if ((flags & REMOVE_EMPTY_PARENTS_REF) && + rmdir(git_path("%s", buf.buf))) + flags &= ~REMOVE_EMPTY_PARENTS_REF; + if ((flags & REMOVE_EMPTY_PARENTS_REFLOG) && + rmdir(git_path("logs/%s", buf.buf))) + flags &= ~REMOVE_EMPTY_PARENTS_REFLOG; } strbuf_release(&buf); } @@ -2334,7 +2346,7 @@ static void prune_ref(struct ref_to_prune *r) } ref_transaction_free(transaction); strbuf_release(&err); - try_remove_empty_parents(r->name); + try_remove_empty_parents(r->name, REMOVE_EMPTY_PARENTS_REF); } static void prune_refs(struct ref_to_prune *r)