diff options
author | Junio C Hamano <gitster@pobox.com> | 2017-11-15 12:14:29 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-11-15 12:14:29 +0900 |
commit | a97222978ab3e0e86e87dccacf59269a9060de9e (patch) | |
tree | f1df1c3ca9d591a3a5dc063041bf537106ce068b /refs/files-backend.c | |
parent | 61f68f607367293d0edb5c297094da1d83cd7fcb (diff) | |
parent | 78fb457968591887ebb331d3d0475c00c7dbb317 (diff) | |
download | git-a97222978ab3e0e86e87dccacf59269a9060de9e.tar.gz git-a97222978ab3e0e86e87dccacf59269a9060de9e.tar.xz |
Merge branch 'mh/tidy-ref-update-flags'
Code clean-up in refs API implementation.
* mh/tidy-ref-update-flags:
refs: update some more docs to use "oid" rather than "sha1"
write_packed_entry(): take `object_id` arguments
refs: rename constant `REF_ISPRUNING` to `REF_IS_PRUNING`
refs: rename constant `REF_NODEREF` to `REF_NO_DEREF`
refs: tidy up and adjust visibility of the `ref_update` flags
ref_transaction_add_update(): remove a check
ref_transaction_update(): die on disallowed flags
prune_ref(): call `ref_transaction_add_update()` directly
files_transaction_prepare(): don't leak flags to packed transaction
Diffstat (limited to 'refs/files-backend.c')
-rw-r--r-- | refs/files-backend.c | 132 |
1 files changed, 94 insertions, 38 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c index b956215bf..f75d960e1 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -10,6 +10,51 @@ #include "../object.h" #include "../dir.h" +/* + * This backend uses the following flags in `ref_update::flags` for + * internal bookkeeping purposes. Their numerical values must not + * conflict with REF_NO_DEREF, REF_FORCE_CREATE_REFLOG, REF_HAVE_NEW, + * REF_HAVE_OLD, or REF_IS_PRUNING, which are also stored in + * `ref_update::flags`. + */ + +/* + * Used as a flag in ref_update::flags when a loose ref is being + * pruned. This flag must only be used when REF_NO_DEREF is set. + */ +#define REF_IS_PRUNING (1 << 4) + +/* + * Flag passed to lock_ref_sha1_basic() telling it to tolerate broken + * refs (i.e., because the reference is about to be deleted anyway). + */ +#define REF_DELETING (1 << 5) + +/* + * Used as a flag in ref_update::flags when the lockfile needs to be + * committed. + */ +#define REF_NEEDS_COMMIT (1 << 6) + +/* + * Used as a flag in ref_update::flags when we want to log a ref + * update but not actually perform it. This is used when a symbolic + * ref update is split up. + */ +#define REF_LOG_ONLY (1 << 7) + +/* + * Used as a flag in ref_update::flags when the ref_update was via an + * update to HEAD. + */ +#define REF_UPDATE_VIA_HEAD (1 << 8) + +/* + * Used as a flag in ref_update::flags when the loose reference has + * been deleted. + */ +#define REF_DELETED_LOOSE (1 << 9) + struct ref_lock { char *ref_name; struct lock_file lk; @@ -195,7 +240,7 @@ static void loose_fill_ref_dir(struct ref_store *ref_store, } else if (is_null_oid(&oid)) { /* * It is so astronomically unlikely - * that NULL_SHA1 is the SHA-1 of an + * that null_oid is the OID of an * actual object that we consider its * appearance in a loose reference * file to be repo corruption @@ -428,7 +473,7 @@ static void unlock_ref(struct ref_lock *lock) * are passed to refs_verify_refname_available() for this check. * * If mustexist is not set and the reference is not found or is - * broken, lock the reference anyway but clear sha1. + * broken, lock the reference anyway but clear old_oid. * * Return 0 on success. On failure, write an error message to err and * return TRANSACTION_NAME_CONFLICT or TRANSACTION_GENERIC_ERROR. @@ -989,22 +1034,29 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r) { struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; + int ret = -1; if (check_refname_format(r->name, 0)) return; transaction = ref_store_transaction_begin(&refs->base, &err); - if (!transaction || - ref_transaction_delete(transaction, r->name, &r->oid, - REF_ISPRUNING | REF_NODEREF, NULL, &err) || - ref_transaction_commit(transaction, &err)) { - ref_transaction_free(transaction); + if (!transaction) + goto cleanup; + ref_transaction_add_update( + transaction, r->name, + REF_NO_DEREF | REF_HAVE_NEW | REF_HAVE_OLD | REF_IS_PRUNING, + &null_oid, &r->oid, NULL); + if (ref_transaction_commit(transaction, &err)) + goto cleanup; + + ret = 0; + +cleanup: + if (ret) error("%s", err.buf); - strbuf_release(&err); - return; - } - ref_transaction_free(transaction); strbuf_release(&err); + ref_transaction_free(transaction); + return; } /* @@ -1081,7 +1133,7 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags) */ if (ref_transaction_update(transaction, iter->refname, iter->oid, NULL, - REF_NODEREF, NULL, &err)) + REF_NO_DEREF, NULL, &err)) die("failure preparing to create packed reference %s: %s", iter->refname, err.buf); @@ -1284,7 +1336,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, } if (!copy && refs_delete_ref(&refs->base, logmsg, oldrefname, - &orig_oid, REF_NODEREF)) { + &orig_oid, REF_NO_DEREF)) { error("unable to delete old %s", oldrefname); goto rollback; } @@ -1300,7 +1352,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, &oid, NULL) && refs_delete_ref(&refs->base, NULL, newrefname, - NULL, REF_NODEREF)) { + NULL, REF_NO_DEREF)) { if (errno == EISDIR) { struct strbuf path = STRBUF_INIT; int result; @@ -1325,7 +1377,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, logmoved = log; lock = lock_ref_oid_basic(refs, newrefname, NULL, NULL, NULL, - REF_NODEREF, NULL, &err); + REF_NO_DEREF, NULL, &err); if (!lock) { if (copy) error("unable to copy '%s' to '%s': %s", oldrefname, newrefname, err.buf); @@ -1348,7 +1400,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, rollback: lock = lock_ref_oid_basic(refs, oldrefname, NULL, NULL, NULL, - REF_NODEREF, NULL, &err); + REF_NO_DEREF, NULL, &err); if (!lock) { error("unable to lock %s for rollback: %s", oldrefname, err.buf); strbuf_release(&err); @@ -1596,9 +1648,8 @@ static int files_log_ref_write(struct files_ref_store *refs, } /* - * Write sha1 into the open lockfile, then close the lockfile. On - * errors, rollback the lockfile, fill in *err and - * return -1. + * Write oid into the open lockfile, then close the lockfile. On + * errors, rollback the lockfile, fill in *err and return -1. */ static int write_ref_to_lockfile(struct ref_lock *lock, const struct object_id *oid, struct strbuf *err) @@ -1764,7 +1815,7 @@ static int files_create_symref(struct ref_store *ref_store, int ret; lock = lock_ref_oid_basic(refs, refname, NULL, - NULL, NULL, REF_NODEREF, NULL, + NULL, NULL, REF_NO_DEREF, NULL, &err); if (!lock) { error("%s", err.buf); @@ -2125,7 +2176,7 @@ static int split_head_update(struct ref_update *update, struct ref_update *new_update; if ((update->flags & REF_LOG_ONLY) || - (update->flags & REF_ISPRUNING) || + (update->flags & REF_IS_PRUNING) || (update->flags & REF_UPDATE_VIA_HEAD)) return 0; @@ -2148,7 +2199,7 @@ static int split_head_update(struct ref_update *update, new_update = ref_transaction_add_update( transaction, "HEAD", - update->flags | REF_LOG_ONLY | REF_NODEREF, + update->flags | REF_LOG_ONLY | REF_NO_DEREF, &update->new_oid, &update->old_oid, update->msg); @@ -2167,8 +2218,8 @@ static int split_head_update(struct ref_update *update, /* * update is for a symref that points at referent and doesn't have - * REF_NODEREF set. Split it into two updates: - * - The original update, but with REF_LOG_ONLY and REF_NODEREF set + * REF_NO_DEREF set. Split it into two updates: + * - The original update, but with REF_LOG_ONLY and REF_NO_DEREF set * - A new, separate update for the referent reference * Note that the new update will itself be subject to splitting when * the iteration gets to it. @@ -2220,10 +2271,10 @@ static int split_symref_update(struct files_ref_store *refs, /* * Change the symbolic ref update to log only. Also, it - * doesn't need to check its old SHA-1 value, as that will be + * doesn't need to check its old OID value, as that will be * done when new_update is processed. */ - update->flags |= REF_LOG_ONLY | REF_NODEREF; + update->flags |= REF_LOG_ONLY | REF_NO_DEREF; update->flags &= ~REF_HAVE_OLD; /* @@ -2289,10 +2340,10 @@ static int check_old_oid(struct ref_update *update, struct object_id *oid, * Prepare for carrying out update: * - Lock the reference referred to by update. * - Read the reference under lock. - * - Check that its old SHA-1 value (if specified) is correct, and in + * - Check that its old OID value (if specified) is correct, and in * any case record it in update->lock->old_oid for later use when * writing the reflog. - * - If it is a symref update without REF_NODEREF, split it up into a + * - If it is a symref update without REF_NO_DEREF, split it up into a * REF_LOG_ONLY update of the symref and add a separate update for * the referent to transaction. * - If it is an update of head_ref, add a corresponding REF_LOG_ONLY @@ -2340,11 +2391,11 @@ static int lock_ref_for_update(struct files_ref_store *refs, update->backend_data = lock; if (update->type & REF_ISSYMREF) { - if (update->flags & REF_NODEREF) { + if (update->flags & REF_NO_DEREF) { /* * We won't be reading the referent as part of * the transaction, so we have to read it here - * to record and possibly check old_sha1: + * to record and possibly check old_oid: */ if (refs_read_ref_full(&refs->base, referent.buf, 0, @@ -2364,7 +2415,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, /* * Create a new update for the reference this * symref is pointing at. Also, we will record - * and verify old_sha1 for this update as part + * and verify old_oid for this update as part * of processing the split-off update, so we * don't have to do it here. */ @@ -2384,7 +2435,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, /* * If this update is happening indirectly because of a - * symref update, record the old SHA-1 in the parent + * symref update, record the old OID in the parent * update: */ for (parent_update = update->parent_update; @@ -2511,13 +2562,18 @@ static int files_transaction_prepare(struct ref_store *ref_store, * transaction. (If we end up splitting up any updates using * split_symref_update() or split_head_update(), those * functions will check that the new updates don't have the - * same refname as any existing ones.) + * same refname as any existing ones.) Also fail if any of the + * updates use REF_IS_PRUNING without REF_NO_DEREF. */ for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; struct string_list_item *item = string_list_append(&affected_refnames, update->refname); + if ((update->flags & REF_IS_PRUNING) && + !(update->flags & REF_NO_DEREF)) + BUG("REF_IS_PRUNING set without REF_NO_DEREF"); + /* * We store a pointer to update in item->util, but at * the moment we never use the value of this field @@ -2575,7 +2631,7 @@ static int files_transaction_prepare(struct ref_store *ref_store, if (update->flags & REF_DELETING && !(update->flags & REF_LOG_ONLY) && - !(update->flags & REF_ISPRUNING)) { + !(update->flags & REF_IS_PRUNING)) { /* * This reference has to be deleted from * packed-refs if it exists there. @@ -2594,8 +2650,8 @@ static int files_transaction_prepare(struct ref_store *ref_store, ref_transaction_add_update( packed_transaction, update->refname, - update->flags & ~REF_HAVE_OLD, - &update->new_oid, &update->old_oid, + REF_HAVE_NEW | REF_NO_DEREF, + &update->new_oid, NULL, NULL); } } @@ -2708,7 +2764,7 @@ static int files_transaction_finish(struct ref_store *ref_store, struct ref_update *update = transaction->updates[i]; if (update->flags & REF_DELETING && !(update->flags & REF_LOG_ONLY) && - !(update->flags & REF_ISPRUNING)) { + !(update->flags & REF_IS_PRUNING)) { strbuf_reset(&sb); files_reflog_path(refs, &sb, update->refname); if (!unlink_or_warn(sb.buf)) @@ -2954,7 +3010,7 @@ static int files_reflog_expire(struct ref_store *ref_store, * reference if --updateref was specified: */ lock = lock_ref_oid_basic(refs, refname, oid, - NULL, NULL, REF_NODEREF, + NULL, NULL, REF_NO_DEREF, &type, &err); if (!lock) { error("cannot lock ref '%s': %s", refname, err.buf); |