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>
Michael Haggerty committed
Jun 22, 2015 at 16:02 UTC
7fa7dc8904882a40107af71a751bad5d1572ba4c
1 file changed
+22
-3
refs.c
+22
-3
@@ -2835,9 +2835,26 @@ int delete_refs(struct string_list *refnames)
2835
struct strbuf err = STRBUF_INIT;
2836
int i, result = 0;
2837
2838
- if (repack_without_refs(refnames, &err))
2839
- result |= error("%s", err.buf);
2840
- strbuf_release(&err);
2838
+ if (!refnames->nr)
2839
+ return 0;
2840
+
2841
+ result = repack_without_refs(refnames, &err);
2842
+ if (result) {
2843
+ /*
2844
+ * If we failed to rewrite the packed-refs file, then
2845
+ * it is unsafe to try to remove loose refs, because
2846
+ * doing so might expose an obsolete packed value for
2847
+ * a reference that might even point at an object that
2848
+ * has been garbage collected.
2849
+ */
2850
+ if (refnames->nr == 1)
2851
+ error(_("could not delete reference %s: %s"),
2852
+ refnames->items[0].string, err.buf);
2853
+ else
2854
+ error(_("could not delete references: %s"), err.buf);
2855
+
2856
+ goto out;
2857
+ }
2858
2859
for (i = 0; i < refnames->nr; i++) {
2860
const char *refname = refnames->items[i].string;
@@ -2846,6 +2863,8 @@ int delete_refs(struct string_list *refnames)
2863
result |= error(_("could not remove reference %s"), refname);
2864
}
2865
2866
+out:
2867
+ strbuf_release(&err);
2868
return result;
2869
}
2870