Commit 91123661 by Carlos Martín Nieto

refdb: add conditional symbolic updates

Add a parameter to the backend to allow checking for the old symbolic
target.
parent d6236cf6
......@@ -95,7 +95,7 @@ struct git_refdb_backend {
int (*write)(git_refdb_backend *backend,
const git_reference *ref, int force,
const git_signature *who, const char *message,
const git_oid *old);
const git_oid *old, const char *old_target);
int (*rename)(
git_reference **out, git_refdb_backend *backend,
......
......@@ -167,14 +167,14 @@ void git_refdb_iterator_free(git_reference_iterator *iter)
iter->free(iter);
}
int git_refdb_write(git_refdb *db, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old)
int git_refdb_write(git_refdb *db, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old_id, const char *old_target)
{
assert(db && db->backend);
GIT_REFCOUNT_INC(db);
ref->db = db;
return db->backend->write(db->backend, ref, force, who, message, old);
return db->backend->write(db->backend, ref, force, who, message, old_id, old_target);
}
int git_refdb_rename(
......
......@@ -42,7 +42,7 @@ int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter);
int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter);
void git_refdb_iterator_free(git_reference_iterator *iter);
int git_refdb_write(git_refdb *refdb, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old);
int git_refdb_write(git_refdb *refdb, git_reference *ref, int force, const git_signature *who, const char *message, const git_oid *old_id, const char *old_target);
int git_refdb_delete(git_refdb *refdb, const char *ref_name);
int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name);
......
......@@ -936,12 +936,13 @@ static int refdb_fs_backend__write(
int force,
const git_signature *who,
const char *message,
const git_oid *old_id)
const git_oid *old_id,
const char *old_target)
{
refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
git_filebuf file = GIT_FILEBUF_INIT;
git_reference *old_ref;
int error = 0, cmp;
git_reference *old_ref = NULL;
int error = 0, cmp = 0;
assert(backend);
......@@ -953,25 +954,25 @@ static int refdb_fs_backend__write(
if ((error = loose_lock(&file, backend, ref)) < 0)
return error;
if (old_id) {
if (old_id || old_target) {
if ((error = refdb_fs_backend__lookup(&old_ref, _backend, ref->name)) < 0)
goto on_error;
}
if (old_ref->type == GIT_REF_SYMBOLIC) {
git_reference_free(old_ref);
giterr_set(GITERR_REFERENCE, "cannot compare id to symbolic reference target");
error = -1;
goto on_error;
}
/* Finally we can compare the ids */
if (old_id && old_ref->type == GIT_REF_OID) {
cmp = git_oid_cmp(old_id, &old_ref->target.oid);
git_reference_free(old_ref);
if (cmp) {
giterr_set(GITERR_REFERENCE, "old reference value does not match");
error = GIT_EMODIFIED;
goto on_error;
}
}
if (old_target && old_ref->type == GIT_REF_SYMBOLIC) {
cmp = git__strcmp(old_target, old_ref->target.symbolic);
git_reference_free(old_ref);
}
if (cmp) {
giterr_set(GITERR_REFERENCE, "old reference value does not match");
error = GIT_EMODIFIED;
goto on_error;
}
if (should_write_reflog(backend->repo, ref->name) &&
......
......@@ -332,7 +332,8 @@ static int reference__create(
int force,
const git_signature *signature,
const char *log_message,
const git_oid *old_id)
const git_oid *old_id,
const char *old_target)
{
char normalized[GIT_REFNAME_MAX];
git_refdb *refdb;
......@@ -381,7 +382,7 @@ static int reference__create(
GITERR_CHECK_ALLOC(ref);
if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id)) < 0) {
if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id, old_target)) < 0) {
git_reference_free(ref);
return error;
}
......@@ -431,7 +432,7 @@ int git_reference_create_matching(
}
error = reference__create(
ref_out, repo, name, id, NULL, force, signature, log_message, old_id);
ref_out, repo, name, id, NULL, force, signature, log_message, old_id, NULL);
git_signature_free(who);
return error;
......@@ -471,7 +472,7 @@ int git_reference_symbolic_create(
}
error = reference__create(
ref_out, repo, name, NULL, target, force, signature, log_message, NULL);
ref_out, repo, name, NULL, target, force, signature, log_message, NULL, NULL);
git_signature_free(who);
return error;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment