diff options
Diffstat (limited to 'refs/refs-internal.h')
-rw-r--r-- | refs/refs-internal.h | 210 |
1 files changed, 122 insertions, 88 deletions
diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 3d46131efb..dd834314bd 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -8,58 +8,28 @@ */ /* - * Flag passed to lock_ref_sha1_basic() telling it to tolerate broken - * refs (i.e., because the reference is about to be deleted anyway). + * The following flags can appear in `ref_update::flags`. Their + * numerical values must not conflict with those of REF_NO_DEREF and + * REF_FORCE_CREATE_REFLOG, which are also stored in + * `ref_update::flags`. */ -#define REF_DELETING 0x02 /* - * Used as a flag in ref_update::flags when a loose ref is being - * pruned. This flag must only be used when REF_NODEREF is set. + * The reference should be updated to new_oid. */ -#define REF_ISPRUNING 0x04 +#define REF_HAVE_NEW (1 << 2) /* - * Used as a flag in ref_update::flags when the reference should be - * updated to new_sha1. + * The current reference's value should be checked to make sure that + * it agrees with old_oid. */ -#define REF_HAVE_NEW 0x08 +#define REF_HAVE_OLD (1 << 3) /* - * Used as a flag in ref_update::flags when old_sha1 should be - * checked. + * Return the length of time to retry acquiring a loose reference lock + * before giving up, in milliseconds: */ -#define REF_HAVE_OLD 0x10 - -/* - * Used as a flag in ref_update::flags when the lockfile needs to be - * committed. - */ -#define REF_NEEDS_COMMIT 0x20 - -/* - * 0x40 is REF_FORCE_CREATE_REFLOG, so skip it if you're adding a - * value to ref_update::flags - */ - -/* - * 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 0x80 - -/* - * Internal flag, meaning that the containing ref_update was via an - * update to HEAD. - */ -#define REF_UPDATE_VIA_HEAD 0x100 - -/* - * Used as a flag in ref_update::flags when the loose reference has - * been deleted. - */ -#define REF_DELETED_LOOSE 0x200 +long get_files_ref_lock_timeout_ms(void); /* * Return true iff refname is minimally safe. "Safe" here means that @@ -77,6 +47,15 @@ */ int refname_is_safe(const char *refname); +/* + * Helper function: return true if refname, which has the specified + * oid and flags, can be resolved to an object in the database. If the + * referred-to object does not exist, emit a warning and return false. + */ +int ref_resolves_to_object(const char *refname, + const struct object_id *oid, + unsigned int flags); + enum peel_status { /* object was peeled successfully: */ PEEL_PEELED = 0, @@ -105,11 +84,11 @@ enum peel_status { /* * Peel the named object; i.e., if the object is a tag, resolve the * tag recursively until a non-tag is found. If successful, store the - * result to sha1 and return PEEL_PEELED. If the object is not a tag + * result to oid and return PEEL_PEELED. If the object is not a tag * or is not valid, return PEEL_NON_TAG or PEEL_INVALID, respectively, - * and leave sha1 unchanged. + * and leave oid unchanged. */ -enum peel_status peel_object(const unsigned char *name, unsigned char *sha1); +enum peel_status peel_object(const struct object_id *name, struct object_id *oid); /* * Copy the reflog message msg to buf, which has been allocated sufficiently @@ -119,30 +98,29 @@ enum peel_status peel_object(const unsigned char *name, unsigned char *sha1); int copy_reflog_msg(char *buf, const char *msg); /** - * Information needed for a single ref update. Set new_sha1 to the new - * value or to null_sha1 to delete the ref. To check the old value - * while the ref is locked, set (flags & REF_HAVE_OLD) and set - * old_sha1 to the old value, or to null_sha1 to ensure the ref does - * not exist before update. + * Information needed for a single ref update. Set new_oid to the new + * value or to null_oid to delete the ref. To check the old value + * while the ref is locked, set (flags & REF_HAVE_OLD) and set old_oid + * to the old value, or to null_oid to ensure the ref does not exist + * before update. */ struct ref_update { - /* - * If (flags & REF_HAVE_NEW), set the reference to this value: + * If (flags & REF_HAVE_NEW), set the reference to this value + * (or delete it, if `new_oid` is `null_oid`). */ - unsigned char new_sha1[20]; + struct object_id new_oid; /* * If (flags & REF_HAVE_OLD), check that the reference - * previously had this value: + * previously had this value (or didn't previously exist, if + * `old_oid` is `null_oid`). */ - unsigned char old_sha1[20]; + struct object_id old_oid; /* - * One or more of REF_HAVE_NEW, REF_HAVE_OLD, REF_NODEREF, - * REF_DELETING, REF_ISPRUNING, REF_LOG_ONLY, - * REF_UPDATE_VIA_HEAD, REF_NEEDS_COMMIT, and - * REF_DELETED_LOOSE: + * One or more of REF_NO_DEREF, REF_FORCE_CREATE_REFLOG, + * REF_HAVE_NEW, REF_HAVE_OLD, or backend-specific flags. */ unsigned int flags; @@ -166,36 +144,54 @@ struct ref_update { }; int refs_read_raw_ref(struct ref_store *ref_store, - const char *refname, unsigned char *sha1, + const char *refname, struct object_id *oid, struct strbuf *referent, unsigned int *type); /* + * Write an error to `err` and return a nonzero value iff the same + * refname appears multiple times in `refnames`. `refnames` must be + * sorted on entry to this function. + */ +int ref_update_reject_duplicates(struct string_list *refnames, + struct strbuf *err); + +/* * Add a ref_update with the specified properties to transaction, and * return a pointer to the new object. This function does not verify - * that refname is well-formed. new_sha1 and old_sha1 are only + * that refname is well-formed. new_oid and old_oid are only * dereferenced if the REF_HAVE_NEW and REF_HAVE_OLD bits, * respectively, are set in flags. */ struct ref_update *ref_transaction_add_update( struct ref_transaction *transaction, const char *refname, unsigned int flags, - const unsigned char *new_sha1, - const unsigned char *old_sha1, + const struct object_id *new_oid, + const struct object_id *old_oid, const char *msg); /* * Transaction states. - * OPEN: The transaction is in a valid state and can accept new updates. - * An OPEN transaction can be committed. - * CLOSED: A closed transaction is no longer active and no other operations - * than free can be used on it in this state. - * A transaction can either become closed by successfully committing - * an active transaction or if there is a failure while building - * the transaction thus rendering it failed/inactive. + * + * OPEN: The transaction is initialized and new updates can still be + * added to it. An OPEN transaction can be prepared, + * committed, freed, or aborted (freeing and aborting an open + * transaction are equivalent). + * + * PREPARED: ref_transaction_prepare(), which locks all of the + * references involved in the update and checks that the + * update has no errors, has been called successfully for the + * transaction. A PREPARED transaction can be committed or + * aborted. + * + * CLOSED: The transaction is no longer active. A transaction becomes + * CLOSED if there is a failure while building the transaction + * or if a transaction is committed or aborted. A CLOSED + * transaction can only be freed. */ enum ref_transaction_state { - REF_TRANSACTION_OPEN = 0, - REF_TRANSACTION_CLOSED = 1 + REF_TRANSACTION_OPEN = 0, + REF_TRANSACTION_PREPARED = 1, + REF_TRANSACTION_CLOSED = 2 }; /* @@ -209,6 +205,7 @@ struct ref_transaction { size_t alloc; size_t nr; enum ref_transaction_state state; + void *backend_data; }; /* @@ -295,6 +292,13 @@ int refs_rename_ref_available(struct ref_store *refs, */ struct ref_iterator { struct ref_iterator_vtable *vtable; + + /* + * Does this `ref_iterator` iterate over references in order + * by refname? + */ + unsigned int ordered : 1; + const char *refname; const struct object_id *oid; unsigned int flags; @@ -340,7 +344,7 @@ int is_empty_ref_iterator(struct ref_iterator *ref_iterator); * which the refname begins with prefix. If trim is non-zero, then * trim that many characters off the beginning of each refname. flags * can be DO_FOR_EACH_INCLUDE_BROKEN to include broken references in - * the iteration. + * the iteration. The output is ordered by refname. */ struct ref_iterator *refs_ref_iterator_begin( struct ref_store *refs, @@ -366,9 +370,11 @@ typedef enum iterator_selection ref_iterator_select_fn( * Iterate over the entries from iter0 and iter1, with the values * interleaved as directed by the select function. The iterator takes * ownership of iter0 and iter1 and frees them when the iteration is - * over. + * over. A derived class should set `ordered` to 1 or 0 based on + * whether it generates its output in order by reference name. */ struct ref_iterator *merge_ref_iterator_begin( + int ordered, struct ref_iterator *iter0, struct ref_iterator *iter1, ref_iterator_select_fn *select, void *cb_data); @@ -397,6 +403,8 @@ struct ref_iterator *overlay_ref_iterator_begin( * As an convenience to callers, if prefix is the empty string and * trim is zero, this function returns iter0 directly, without * wrapping it. + * + * The resulting ref_iterator is ordered if iter0 is. */ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, const char *prefix, @@ -407,11 +415,14 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, /* * Base class constructor for ref_iterators. Initialize the * ref_iterator part of iter, setting its vtable pointer as specified. + * `ordered` should be set to 1 if the iterator will iterate over + * references in order by refname; otherwise it should be set to 0. * This is meant to be called only by the initializers of derived * classes. */ void base_ref_iterator_init(struct ref_iterator *iter, - struct ref_iterator_vtable *vtable); + struct ref_iterator_vtable *vtable, + int ordered); /* * Base class destructor for ref_iterators. Destroy the ref_iterator @@ -482,6 +493,10 @@ struct ref_store; #define REF_STORE_WRITE (1 << 1) /* can perform update operations */ #define REF_STORE_ODB (1 << 2) /* has access to object database */ #define REF_STORE_MAIN (1 << 3) +#define REF_STORE_ALL_CAPS (REF_STORE_READ | \ + REF_STORE_WRITE | \ + REF_STORE_ODB | \ + REF_STORE_MAIN) /* * Initialize the ref_store for the specified gitdir. These functions @@ -493,27 +508,42 @@ typedef struct ref_store *ref_store_init_fn(const char *gitdir, typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err); +typedef int ref_transaction_prepare_fn(struct ref_store *refs, + struct ref_transaction *transaction, + struct strbuf *err); + +typedef int ref_transaction_finish_fn(struct ref_store *refs, + struct ref_transaction *transaction, + struct strbuf *err); + +typedef int ref_transaction_abort_fn(struct ref_store *refs, + struct ref_transaction *transaction, + struct strbuf *err); + typedef int ref_transaction_commit_fn(struct ref_store *refs, struct ref_transaction *transaction, struct strbuf *err); typedef int pack_refs_fn(struct ref_store *ref_store, unsigned int flags); -typedef int peel_ref_fn(struct ref_store *ref_store, - const char *refname, unsigned char *sha1); typedef int create_symref_fn(struct ref_store *ref_store, const char *ref_target, const char *refs_heads_master, const char *logmsg); -typedef int delete_refs_fn(struct ref_store *ref_store, +typedef int delete_refs_fn(struct ref_store *ref_store, const char *msg, struct string_list *refnames, unsigned int flags); typedef int rename_ref_fn(struct ref_store *ref_store, const char *oldref, const char *newref, const char *logmsg); +typedef int copy_ref_fn(struct ref_store *ref_store, + const char *oldref, const char *newref, + const char *logmsg); /* - * Iterate over the references in the specified ref_store that are - * within find_containing_dir(prefix). If prefix is NULL or the empty - * string, iterate over all references in the submodule. + * Iterate over the references in `ref_store` whose names start with + * `prefix`. `prefix` is matched as a literal string, without regard + * for path separators. If prefix is NULL or the empty string, iterate + * over all references in `ref_store`. The output is ordered by + * refname. */ typedef struct ref_iterator *ref_iterator_begin_fn( struct ref_store *ref_store, @@ -541,7 +571,7 @@ typedef int create_reflog_fn(struct ref_store *ref_store, const char *refname, int force_create, struct strbuf *err); typedef int delete_reflog_fn(struct ref_store *ref_store, const char *refname); typedef int reflog_expire_fn(struct ref_store *ref_store, - const char *refname, const unsigned char *sha1, + const char *refname, const struct object_id *oid, unsigned int flags, reflog_expiry_prepare_fn prepare_fn, reflog_expiry_should_prune_fn should_prune_fn, @@ -552,13 +582,13 @@ typedef int reflog_expire_fn(struct ref_store *ref_store, * Read a reference from the specified reference store, non-recursively. * Set type to describe the reference, and: * - * - If refname is the name of a normal reference, fill in sha1 + * - If refname is the name of a normal reference, fill in oid * (leaving referent unchanged). * * - If refname is the name of a symbolic reference, write the full * name of the reference to which it refers (e.g. * "refs/heads/master") to referent and set the REF_ISSYMREF bit in - * type (leaving sha1 unchanged). The caller is responsible for + * type (leaving oid unchanged). The caller is responsible for * validating that referent is a valid reference name. * * WARNING: refname might be used as part of a filename, so it is @@ -570,7 +600,7 @@ typedef int reflog_expire_fn(struct ref_store *ref_store, * * Return 0 on success. If the ref doesn't exist, set errno to ENOENT * and return -1. If the ref exists but is neither a symbolic ref nor - * a sha1, it is broken; set REF_ISBROKEN in type, set errno to + * an object ID, it is broken; set REF_ISBROKEN in type, set errno to * EINVAL, and return -1. If there is another error reading the ref, * set errno appropriately and return -1. * @@ -587,7 +617,7 @@ typedef int reflog_expire_fn(struct ref_store *ref_store, * refname will still be valid and unchanged. */ typedef int read_raw_ref_fn(struct ref_store *ref_store, - const char *refname, unsigned char *sha1, + const char *refname, struct object_id *oid, struct strbuf *referent, unsigned int *type); struct ref_storage_be { @@ -595,14 +625,17 @@ struct ref_storage_be { const char *name; ref_store_init_fn *init; ref_init_db_fn *init_db; - ref_transaction_commit_fn *transaction_commit; + + ref_transaction_prepare_fn *transaction_prepare; + ref_transaction_finish_fn *transaction_finish; + ref_transaction_abort_fn *transaction_abort; ref_transaction_commit_fn *initial_transaction_commit; pack_refs_fn *pack_refs; - peel_ref_fn *peel_ref; create_symref_fn *create_symref; delete_refs_fn *delete_refs; rename_ref_fn *rename_ref; + copy_ref_fn *copy_ref; ref_iterator_begin_fn *iterator_begin; read_raw_ref_fn *read_raw_ref; @@ -617,6 +650,7 @@ struct ref_storage_be { }; extern struct ref_storage_be refs_be_files; +extern struct ref_storage_be refs_be_packed; /* * A representation of the reference store for the main repository or |