diff --git a/refs/packed-backend.c b/refs/packed-backend.c index a73fc6aca7..53511f2d91 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -879,6 +879,9 @@ struct packed_ref_iterator { /* The current position in the snapshot's buffer: */ const char *pos; + /* The starting position of the current ref record. */ + const char *record_start; + /* The end of the part of the buffer that will be iterated over: */ const char *eof; @@ -933,6 +936,7 @@ static int next_record(struct packed_ref_iterator *iter) if (iter->pos == iter->eof) return ITER_DONE; + iter->record_start = iter->pos; iter->base.ref.flags = REF_ISPACKED; p = iter->pos; @@ -1530,9 +1534,15 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re } if (cmp < 0) { - /* Pass the old reference through. */ - if (write_packed_entry(out, iter->ref.name, - iter->ref.oid, iter->ref.peeled_oid)) + const struct packed_ref_iterator *packed_iter = + (const struct packed_ref_iterator *)iter; + size_t len = packed_iter->pos - packed_iter->record_start; + + /* + * Skip any formatting and directly write to the packed-refs file + * when deleting references and writing the remaining refs verbatim. + */ + if (fwrite(packed_iter->record_start, len, 1, out) != 1) goto write_error; if ((ok = ref_iterator_advance(iter)) != ITER_OK) {