зеркало из https://github.com/microsoft/git.git
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
This commit is contained in:
Коммит
a97222978a
2
bisect.c
2
bisect.c
|
@ -1073,7 +1073,7 @@ int bisect_clean_state(void)
|
|||
struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;
|
||||
for_each_ref_in("refs/bisect", mark_for_removal, (void *) &refs_for_removal);
|
||||
string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));
|
||||
result = delete_refs("bisect: remove", &refs_for_removal, REF_NODEREF);
|
||||
result = delete_refs("bisect: remove", &refs_for_removal, REF_NO_DEREF);
|
||||
refs_for_removal.strdup_strings = 1;
|
||||
string_list_clear(&refs_for_removal, 0);
|
||||
unlink_or_warn(git_path_bisect_expected_rev());
|
||||
|
|
|
@ -2148,7 +2148,7 @@ static void am_abort(struct am_state *state)
|
|||
has_curr_head ? &curr_head : NULL, 0,
|
||||
UPDATE_REFS_DIE_ON_ERR);
|
||||
else if (curr_branch)
|
||||
delete_ref(NULL, curr_branch, NULL, REF_NODEREF);
|
||||
delete_ref(NULL, curr_branch, NULL, REF_NO_DEREF);
|
||||
|
||||
free(curr_branch);
|
||||
am_destroy(state);
|
||||
|
|
|
@ -258,7 +258,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
|
|||
}
|
||||
|
||||
if (delete_ref(NULL, name, is_null_oid(&oid) ? NULL : &oid,
|
||||
REF_NODEREF)) {
|
||||
REF_NO_DEREF)) {
|
||||
error(remote_branch
|
||||
? _("Error deleting remote-tracking branch '%s'")
|
||||
: _("Error deleting branch '%s'"),
|
||||
|
|
|
@ -663,7 +663,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
|
|||
/* Nothing to do. */
|
||||
} else if (opts->force_detach || !new->path) { /* No longer on any branch. */
|
||||
update_ref(msg.buf, "HEAD", &new->commit->object.oid, NULL,
|
||||
REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
|
||||
REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);
|
||||
if (!opts->quiet) {
|
||||
if (old->path &&
|
||||
advice_detached_head && !opts->force_detach)
|
||||
|
|
|
@ -689,7 +689,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
|
|||
} else if (our) {
|
||||
struct commit *c = lookup_commit_reference(&our->old_oid);
|
||||
/* --branch specifies a non-branch (i.e. tags), detach HEAD */
|
||||
update_ref(msg, "HEAD", &c->object.oid, NULL, REF_NODEREF,
|
||||
update_ref(msg, "HEAD", &c->object.oid, NULL, REF_NO_DEREF,
|
||||
UPDATE_REFS_DIE_ON_ERR);
|
||||
} else if (remote) {
|
||||
/*
|
||||
|
@ -697,7 +697,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
|
|||
* HEAD points to a branch but we don't know which one.
|
||||
* Detach HEAD in all these cases.
|
||||
*/
|
||||
update_ref(msg, "HEAD", &remote->old_oid, NULL, REF_NODEREF,
|
||||
update_ref(msg, "HEAD", &remote->old_oid, NULL, REF_NO_DEREF,
|
||||
UPDATE_REFS_DIE_ON_ERR);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -686,7 +686,7 @@ static int merge_abort(struct notes_merge_options *o)
|
|||
|
||||
if (delete_ref(NULL, "NOTES_MERGE_PARTIAL", NULL, 0))
|
||||
ret += error(_("failed to delete ref NOTES_MERGE_PARTIAL"));
|
||||
if (delete_ref(NULL, "NOTES_MERGE_REF", NULL, REF_NODEREF))
|
||||
if (delete_ref(NULL, "NOTES_MERGE_REF", NULL, REF_NO_DEREF))
|
||||
ret += error(_("failed to delete ref NOTES_MERGE_REF"));
|
||||
if (notes_merge_abort(o))
|
||||
ret += error(_("failed to remove 'git notes merge' worktree"));
|
||||
|
|
|
@ -693,7 +693,7 @@ static int mv(int argc, const char **argv)
|
|||
read_ref_full(item->string, RESOLVE_REF_READING, &oid, &flag);
|
||||
if (!(flag & REF_ISSYMREF))
|
||||
continue;
|
||||
if (delete_ref(NULL, item->string, NULL, REF_NODEREF))
|
||||
if (delete_ref(NULL, item->string, NULL, REF_NO_DEREF))
|
||||
die(_("deleting '%s' failed"), item->string);
|
||||
}
|
||||
for (i = 0; i < remote_branches.nr; i++) {
|
||||
|
@ -788,7 +788,7 @@ static int rm(int argc, const char **argv)
|
|||
strbuf_release(&buf);
|
||||
|
||||
if (!result)
|
||||
result = delete_refs("remote: remove", &branches, REF_NODEREF);
|
||||
result = delete_refs("remote: remove", &branches, REF_NO_DEREF);
|
||||
string_list_clear(&branches, 0);
|
||||
|
||||
if (skipped.nr) {
|
||||
|
@ -1255,7 +1255,7 @@ static int set_head(int argc, const char **argv)
|
|||
head_name = xstrdup(states.heads.items[0].string);
|
||||
free_remote_ref_states(&states);
|
||||
} else if (opt_d && !opt_a && argc == 1) {
|
||||
if (delete_ref(NULL, buf.buf, NULL, REF_NODEREF))
|
||||
if (delete_ref(NULL, buf.buf, NULL, REF_NO_DEREF))
|
||||
result |= error(_("Could not delete %s"), buf.buf);
|
||||
} else
|
||||
usage_with_options(builtin_remote_sethead_usage, options);
|
||||
|
|
|
@ -58,7 +58,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
|
|||
die("Cannot delete %s, not a symbolic ref", argv[0]);
|
||||
if (!strcmp(argv[0], "HEAD"))
|
||||
die("deleting '%s' is not allowed", argv[0]);
|
||||
return delete_ref(NULL, argv[0], NULL, REF_NODEREF);
|
||||
return delete_ref(NULL, argv[0], NULL, REF_NO_DEREF);
|
||||
}
|
||||
|
||||
switch (argc) {
|
||||
|
|
|
@ -312,7 +312,7 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
|
|||
static const char *parse_cmd_option(struct strbuf *input, const char *next)
|
||||
{
|
||||
if (!strncmp(next, "no-deref", 8) && next[8] == line_termination)
|
||||
update_flags |= REF_NODEREF;
|
||||
update_flags |= REF_NO_DEREF;
|
||||
else
|
||||
die("option unknown: %s", next);
|
||||
return next + 8;
|
||||
|
@ -427,7 +427,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
if (no_deref)
|
||||
flags = REF_NODEREF;
|
||||
flags = REF_NO_DEREF;
|
||||
if (delete)
|
||||
/*
|
||||
* For purposes of backwards compatibility, we treat
|
||||
|
|
8
refs.c
8
refs.c
|
@ -770,7 +770,7 @@ static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid,
|
|||
if (cb->cutoff_cnt)
|
||||
*cb->cutoff_cnt = cb->reccnt - 1;
|
||||
/*
|
||||
* we have not yet updated cb->[n|o]sha1 so they still
|
||||
* we have not yet updated cb->[n|o]oid so they still
|
||||
* hold the values for the previous record.
|
||||
*/
|
||||
if (!is_null_oid(&cb->ooid)) {
|
||||
|
@ -906,9 +906,6 @@ struct ref_update *ref_transaction_add_update(
|
|||
if (transaction->state != REF_TRANSACTION_OPEN)
|
||||
die("BUG: update called for transaction that is not open");
|
||||
|
||||
if ((flags & REF_ISPRUNING) && !(flags & REF_NODEREF))
|
||||
die("BUG: REF_ISPRUNING set without REF_NODEREF");
|
||||
|
||||
FLEX_ALLOC_STR(update, refname, refname);
|
||||
ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
|
||||
transaction->updates[transaction->nr++] = update;
|
||||
|
@ -940,7 +937,8 @@ int ref_transaction_update(struct ref_transaction *transaction,
|
|||
return -1;
|
||||
}
|
||||
|
||||
flags &= REF_TRANSACTION_UPDATE_ALLOWED_FLAGS;
|
||||
if (flags & ~REF_TRANSACTION_UPDATE_ALLOWED_FLAGS)
|
||||
BUG("illegal flags 0x%x passed to ref_transaction_update()", flags);
|
||||
|
||||
flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0);
|
||||
|
||||
|
|
77
refs.h
77
refs.h
|
@ -126,7 +126,7 @@ int peel_ref(const char *refname, struct object_id *oid);
|
|||
/**
|
||||
* Resolve refname in the nested "gitlink" repository in the specified
|
||||
* submodule (which must be non-NULL). If the resolution is
|
||||
* successful, return 0 and set sha1 to the name of the object;
|
||||
* successful, return 0 and set oid to the name of the object;
|
||||
* otherwise, return a non-zero value.
|
||||
*/
|
||||
int resolve_gitlink_ref(const char *submodule, const char *refname,
|
||||
|
@ -260,7 +260,7 @@ struct ref_transaction;
|
|||
|
||||
/*
|
||||
* The signature for the callback function for the for_each_*()
|
||||
* functions below. The memory pointed to by the refname and sha1
|
||||
* functions below. The memory pointed to by the refname and oid
|
||||
* arguments is only guaranteed to be valid for the duration of a
|
||||
* single callback invocation.
|
||||
*/
|
||||
|
@ -335,24 +335,6 @@ void warn_dangling_symrefs(FILE *fp, const char *msg_fmt,
|
|||
*/
|
||||
int refs_pack_refs(struct ref_store *refs, unsigned int flags);
|
||||
|
||||
/*
|
||||
* Flags controlling ref_transaction_update(), ref_transaction_create(), etc.
|
||||
* REF_NODEREF: act on the ref directly, instead of dereferencing
|
||||
* symbolic references.
|
||||
*
|
||||
* Other flags are reserved for internal use.
|
||||
*/
|
||||
#define REF_NODEREF 0x01
|
||||
#define REF_FORCE_CREATE_REFLOG 0x40
|
||||
|
||||
/*
|
||||
* Flags that can be passed in to ref_transaction_update
|
||||
*/
|
||||
#define REF_TRANSACTION_UPDATE_ALLOWED_FLAGS \
|
||||
REF_ISPRUNING | \
|
||||
REF_FORCE_CREATE_REFLOG | \
|
||||
REF_NODEREF
|
||||
|
||||
/*
|
||||
* Setup reflog before using. Fill in err and return -1 on failure.
|
||||
*/
|
||||
|
@ -372,7 +354,7 @@ int reflog_exists(const char *refname);
|
|||
|
||||
/*
|
||||
* Delete the specified reference. If old_oid is non-NULL, then
|
||||
* verify that the current value of the reference is old_sha1 before
|
||||
* verify that the current value of the reference is old_oid before
|
||||
* deleting it. If old_oid is NULL, delete the reference if it
|
||||
* exists, regardless of its old value. It is an error for old_oid to
|
||||
* be null_oid. msg and flags are passed through to
|
||||
|
@ -480,22 +462,23 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err);
|
|||
*
|
||||
* refname -- the name of the reference to be affected.
|
||||
*
|
||||
* new_sha1 -- the SHA-1 that should be set to be the new value of
|
||||
* the reference. Some functions allow this parameter to be
|
||||
* new_oid -- the object ID that should be set to be the new value
|
||||
* of the reference. Some functions allow this parameter to be
|
||||
* NULL, meaning that the reference is not changed, or
|
||||
* null_sha1, meaning that the reference should be deleted. A
|
||||
* null_oid, meaning that the reference should be deleted. A
|
||||
* copy of this value is made in the transaction.
|
||||
*
|
||||
* old_sha1 -- the SHA-1 value that the reference must have before
|
||||
* old_oid -- the object ID that the reference must have before
|
||||
* the update. Some functions allow this parameter to be NULL,
|
||||
* meaning that the old value of the reference is not checked,
|
||||
* or null_sha1, meaning that the reference must not exist
|
||||
* or null_oid, meaning that the reference must not exist
|
||||
* before the update. A copy of this value is made in the
|
||||
* transaction.
|
||||
*
|
||||
* flags -- flags affecting the update, passed to
|
||||
* update_ref_lock(). Can be REF_NODEREF, which means that
|
||||
* symbolic references should not be followed.
|
||||
* update_ref_lock(). Possible flags: REF_NO_DEREF,
|
||||
* REF_FORCE_CREATE_REFLOG. See those constants for more
|
||||
* information.
|
||||
*
|
||||
* msg -- a message describing the change (for the reflog).
|
||||
*
|
||||
|
@ -511,11 +494,37 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err);
|
|||
*/
|
||||
|
||||
/*
|
||||
* Add a reference update to transaction. new_oid is the value that
|
||||
* the reference should have after the update, or null_oid if it
|
||||
* should be deleted. If new_oid is NULL, then the reference is not
|
||||
* changed at all. old_oid is the value that the reference must have
|
||||
* before the update, or null_oid if it must not have existed
|
||||
* The following flags can be passed to ref_transaction_update() etc.
|
||||
* Internally, they are stored in `ref_update::flags`, along with some
|
||||
* internal flags.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Act on the ref directly; i.e., without dereferencing symbolic refs.
|
||||
* If this flag is not specified, then symbolic references are
|
||||
* dereferenced and the update is applied to the referent.
|
||||
*/
|
||||
#define REF_NO_DEREF (1 << 0)
|
||||
|
||||
/*
|
||||
* Force the creation of a reflog for this reference, even if it
|
||||
* didn't previously have a reflog.
|
||||
*/
|
||||
#define REF_FORCE_CREATE_REFLOG (1 << 1)
|
||||
|
||||
/*
|
||||
* Bitmask of all of the flags that are allowed to be passed in to
|
||||
* ref_transaction_update() and friends:
|
||||
*/
|
||||
#define REF_TRANSACTION_UPDATE_ALLOWED_FLAGS \
|
||||
(REF_NO_DEREF | REF_FORCE_CREATE_REFLOG)
|
||||
|
||||
/*
|
||||
* Add a reference update to transaction. `new_oid` is the value that
|
||||
* the reference should have after the update, or `null_oid` if it
|
||||
* should be deleted. If `new_oid` is NULL, then the reference is not
|
||||
* changed at all. `old_oid` is the value that the reference must have
|
||||
* before the update, or `null_oid` if it must not have existed
|
||||
* beforehand. The old value is checked after the lock is taken to
|
||||
* prevent races. If the old value doesn't agree with old_oid, the
|
||||
* whole transaction fails. If old_oid is NULL, then the previous
|
||||
|
@ -624,7 +633,7 @@ int ref_transaction_abort(struct ref_transaction *transaction,
|
|||
* It is a bug to call this function when there might be other
|
||||
* processes accessing the repository or if there are existing
|
||||
* references that might conflict with the ones being created. All
|
||||
* old_sha1 values must either be absent or NULL_SHA1.
|
||||
* old_oid values must either be absent or null_oid.
|
||||
*/
|
||||
int initial_ref_transaction_commit(struct ref_transaction *transaction,
|
||||
struct strbuf *err);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -744,7 +744,7 @@ static int packed_read_raw_ref(struct ref_store *ref_store,
|
|||
/*
|
||||
* This value is set in `base.flags` if the peeled value of the
|
||||
* current reference is known. In that case, `peeled` contains the
|
||||
* correct peeled value for the reference, which might be `null_sha1`
|
||||
* correct peeled value for the reference, which might be `null_oid`
|
||||
* if the reference is not a tag or if it is broken.
|
||||
*/
|
||||
#define REF_KNOWS_PEELED 0x40
|
||||
|
@ -961,11 +961,11 @@ static struct ref_iterator *packed_ref_iterator_begin(
|
|||
* by the failing call to `fprintf()`.
|
||||
*/
|
||||
static int write_packed_entry(FILE *fh, const char *refname,
|
||||
const unsigned char *sha1,
|
||||
const unsigned char *peeled)
|
||||
const struct object_id *oid,
|
||||
const struct object_id *peeled)
|
||||
{
|
||||
if (fprintf(fh, "%s %s\n", sha1_to_hex(sha1), refname) < 0 ||
|
||||
(peeled && fprintf(fh, "^%s\n", sha1_to_hex(peeled)) < 0))
|
||||
if (fprintf(fh, "%s %s\n", oid_to_hex(oid), refname) < 0 ||
|
||||
(peeled && fprintf(fh, "^%s\n", oid_to_hex(peeled)) < 0))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
@ -1203,8 +1203,8 @@ static int write_with_updates(struct packed_ref_store *refs,
|
|||
int peel_error = ref_iterator_peel(iter, &peeled);
|
||||
|
||||
if (write_packed_entry(out, iter->refname,
|
||||
iter->oid->hash,
|
||||
peel_error ? NULL : peeled.hash))
|
||||
iter->oid,
|
||||
peel_error ? NULL : &peeled))
|
||||
goto write_error;
|
||||
|
||||
if ((ok = ref_iterator_advance(iter)) != ITER_OK)
|
||||
|
@ -1224,8 +1224,8 @@ static int write_with_updates(struct packed_ref_store *refs,
|
|||
&peeled);
|
||||
|
||||
if (write_packed_entry(out, update->refname,
|
||||
update->new_oid.hash,
|
||||
peel_error ? NULL : peeled.hash))
|
||||
&update->new_oid,
|
||||
peel_error ? NULL : &peeled))
|
||||
goto write_error;
|
||||
|
||||
i++;
|
||||
|
|
|
@ -260,8 +260,8 @@ int add_ref_entry(struct ref_dir *dir, struct ref_entry *ref)
|
|||
|
||||
/*
|
||||
* Emit a warning and return true iff ref1 and ref2 have the same name
|
||||
* and the same sha1. Die if they have the same name but different
|
||||
* sha1s.
|
||||
* and the same oid. Die if they have the same name but different
|
||||
* oids.
|
||||
*/
|
||||
static int is_dup_ref(const struct ref_entry *ref1, const struct ref_entry *ref2)
|
||||
{
|
||||
|
|
|
@ -8,58 +8,22 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* 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 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.
|
||||
*/
|
||||
#define REF_ISPRUNING 0x04
|
||||
|
||||
/*
|
||||
* Used as a flag in ref_update::flags when the reference should be
|
||||
* updated to new_sha1.
|
||||
*/
|
||||
#define REF_HAVE_NEW 0x08
|
||||
|
||||
/*
|
||||
* Used as a flag in ref_update::flags when old_sha1 should be
|
||||
* checked.
|
||||
*/
|
||||
#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
|
||||
* 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`.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* The reference should be updated to new_oid.
|
||||
*/
|
||||
#define REF_LOG_ONLY 0x80
|
||||
#define REF_HAVE_NEW (1 << 2)
|
||||
|
||||
/*
|
||||
* Internal flag, meaning that the containing ref_update was via an
|
||||
* update to HEAD.
|
||||
* The current reference's value should be checked to make sure that
|
||||
* it agrees with old_oid.
|
||||
*/
|
||||
#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
|
||||
#define REF_HAVE_OLD (1 << 3)
|
||||
|
||||
/*
|
||||
* Return the length of time to retry acquiring a loose reference lock
|
||||
|
@ -122,7 +86,7 @@ enum peel_status {
|
|||
* tag recursively until a non-tag is found. If successful, store the
|
||||
* 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 struct object_id *name, struct object_id *oid);
|
||||
|
||||
|
@ -134,30 +98,29 @@ enum peel_status peel_object(const struct object_id *name, struct object_id *oid
|
|||
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`).
|
||||
*/
|
||||
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`).
|
||||
*/
|
||||
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;
|
||||
|
||||
|
@ -195,7 +158,7 @@ int ref_update_reject_duplicates(struct string_list *refnames,
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
@ -1117,11 +1117,11 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
|
|||
*/
|
||||
if (command == TODO_PICK && !opts->no_commit && (res == 0 || res == 1) &&
|
||||
update_ref(NULL, "CHERRY_PICK_HEAD", &commit->object.oid, NULL,
|
||||
REF_NODEREF, UPDATE_REFS_MSG_ON_ERR))
|
||||
REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))
|
||||
res = -1;
|
||||
if (command == TODO_REVERT && ((opts->no_commit && res == 0) || res == 1) &&
|
||||
update_ref(NULL, "REVERT_HEAD", &commit->object.oid, NULL,
|
||||
REF_NODEREF, UPDATE_REFS_MSG_ON_ERR))
|
||||
REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))
|
||||
res = -1;
|
||||
|
||||
if (res) {
|
||||
|
@ -2130,7 +2130,7 @@ cleanup_head_ref:
|
|||
msg = reflog_message(opts, "finish", "%s onto %s",
|
||||
head_ref.buf, buf.buf);
|
||||
if (update_ref(msg, head_ref.buf, &head, &orig,
|
||||
REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) {
|
||||
REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
|
||||
res = error(_("could not update %s"),
|
||||
head_ref.buf);
|
||||
goto cleanup_head_ref;
|
||||
|
|
Загрузка…
Ссылка в новой задаче