diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2014-02-04 22:04:00 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2014-02-05 12:07:56 +0100 |
commit | 911236619b5d774e33dd9f3de92a7c86c2befb26 (patch) | |
tree | 528d64a959077a604232980cc092f92d04f0e13f /src | |
parent | d6236cf662ebd4ba8ef4902c81a19bbfd92847f9 (diff) | |
download | libgit2-911236619b5d774e33dd9f3de92a7c86c2befb26.tar.gz |
refdb: add conditional symbolic updates
Add a parameter to the backend to allow checking for the old symbolic
target.
Diffstat (limited to 'src')
-rw-r--r-- | src/refdb.c | 4 | ||||
-rw-r--r-- | src/refdb.h | 2 | ||||
-rw-r--r-- | src/refdb_fs.c | 35 | ||||
-rw-r--r-- | src/refs.c | 9 |
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; |