summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/refdb.c4
-rw-r--r--src/refdb.h2
-rw-r--r--src/refdb_fs.c35
-rw-r--r--src/refs.c9
4 files changed, 26 insertions, 24 deletions
diff --git a/src/refdb.c b/src/refdb.c
index 9ff812433..66d943e86 100644
--- a/src/refdb.c
+++ b/src/refdb.c
@@ -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(
diff --git a/src/refdb.h b/src/refdb.h
index 86a1f8971..eabb5969b 100644
--- a/src/refdb.h
+++ b/src/refdb.h
@@ -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);
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index 554fe42c9..879e48514 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -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) &&
diff --git a/src/refs.c b/src/refs.c
index 007fdf353..888b5cb3c 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -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;