From 7fa7dc8904882a40107af71a751bad5d1572ba4c Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Mon, 22 Jun 2015 16:02:57 +0200 Subject: delete_refs(): bail early if the packed-refs file cannot be rewritten If we fail to delete the doomed references from the packed-refs file, then it is unsafe to delete their loose references, because doing so might expose a value from the packed-refs file that is obsolete and perhaps even points at an object that has been garbage collected. So if repack_without_refs() fails, emit a more explicit error message and bail. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano diff --git a/refs.c b/refs.c index cebabc5..e409894 100644 --- a/refs.c +++ b/refs.c @@ -2835,9 +2835,26 @@ int delete_refs(struct string_list *refnames) struct strbuf err = STRBUF_INIT; int i, result = 0; - if (repack_without_refs(refnames, &err)) - result |= error("%s", err.buf); - strbuf_release(&err); + if (!refnames->nr) + return 0; + + result = repack_without_refs(refnames, &err); + if (result) { + /* + * If we failed to rewrite the packed-refs file, then + * it is unsafe to try to remove loose refs, because + * doing so might expose an obsolete packed value for + * a reference that might even point at an object that + * has been garbage collected. + */ + if (refnames->nr == 1) + error(_("could not delete reference %s: %s"), + refnames->items[0].string, err.buf); + else + error(_("could not delete references: %s"), err.buf); + + goto out; + } for (i = 0; i < refnames->nr; i++) { const char *refname = refnames->items[i].string; @@ -2846,6 +2863,8 @@ int delete_refs(struct string_list *refnames) result |= error(_("could not remove reference %s"), refname); } +out: + strbuf_release(&err); return result; } -- cgit v0.10.2-6-g49f6