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 <mhag...@alum.mit.edu>
---
 refs.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/refs.c b/refs.c
index 5386077..19afc4d 100644
--- a/refs.c
+++ b/refs.c
@@ -2823,9 +2823,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;
@@ -2834,6 +2851,8 @@ int delete_refs(struct string_list *refnames)
                        result |= error(_("could not remove reference %s"), 
refname);
        }
 
+out:
+       strbuf_release(&err);
        return result;
 }
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe git" in

Reply via email to