diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2015-06-22 16:02:57 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-06-22 13:17:10 -0700 |
commit | 7fa7dc8904882a40107af71a751bad5d1572ba4c (patch) | |
tree | 45331936e57f959446e630d91c6689d8d6aff834 /refs.c | |
parent | 5d97861b9baf3b0596f2a1c343634062aec2df84 (diff) | |
download | git-7fa7dc8904882a40107af71a751bad5d1572ba4c.tar.gz git-7fa7dc8904882a40107af71a751bad5d1572ba4c.tar.xz |
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 <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 25 |
1 files changed, 22 insertions, 3 deletions
@@ -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; } |