diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2017-09-08 15:51:53 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-09-09 03:18:04 +0900 |
commit | 5e00a6c873981f87165adfecf29ad0ecc2c2c5df (patch) | |
tree | faebf75ef8baa550ec5be76ed261bb7f2b68f97a | |
parent | 9939b33d6a3900e76b9cf95cbbb30ad8cf38cab3 (diff) | |
download | git-5e00a6c873981f87165adfecf29ad0ecc2c2c5df.tar.gz |
files_transaction_finish(): delete reflogs before referencesmh/packed-ref-transactions
If the deletion steps unexpectedly fail, it is less bad to leave a
reference without its reflog than it is to leave a reflog without its
reference, since the latter is an invalid repository state.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | refs/files-backend.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c index 29eb5e826f..961424a4ea 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2637,6 +2637,27 @@ static int files_transaction_finish(struct ref_store *ref_store, } /* + * Now that updates are safely completed, we can perform + * deletes. First delete the reflogs of any references that + * will be deleted, since (in the unexpected event of an + * error) leaving a reference without a reflog is less bad + * than leaving a reflog without a reference (the latter is a + * mildly invalid repository state): + */ + for (i = 0; i < transaction->nr; i++) { + struct ref_update *update = transaction->updates[i]; + if (update->flags & REF_DELETING && + !(update->flags & REF_LOG_ONLY) && + !(update->flags & REF_ISPRUNING)) { + strbuf_reset(&sb); + files_reflog_path(refs, &sb, update->refname); + if (!unlink_or_warn(sb.buf)) + try_remove_empty_parents(refs, update->refname, + REMOVE_EMPTY_PARENTS_REFLOG); + } + } + + /* * Perform deletes now that updates are safely completed. * * First delete any packed versions of the references, while @@ -2672,20 +2693,6 @@ static int files_transaction_finish(struct ref_store *ref_store, } } - /* Delete the reflogs of any references that were deleted: */ - for (i = 0; i < transaction->nr; i++) { - struct ref_update *update = transaction->updates[i]; - if (update->flags & REF_DELETING && - !(update->flags & REF_LOG_ONLY) && - !(update->flags & REF_ISPRUNING)) { - strbuf_reset(&sb); - files_reflog_path(refs, &sb, update->refname); - if (!unlink_or_warn(sb.buf)) - try_remove_empty_parents(refs, update->refname, - REMOVE_EMPTY_PARENTS_REFLOG); - } - } - clear_loose_ref_cache(refs); cleanup: |