Commit fc4728e3 by Carlos Martín Nieto

refs: return GIT_EMODIFIED if the ref target moved

In case we loose the race to update the reference, return GIT_EMODIFIED
to let the user distinguish it from other types of errors.
parent 5d96fe88
......@@ -40,6 +40,7 @@ typedef enum {
GIT_EINVALIDSPEC = -12, /*< Name/ref spec was not in a valid format */
GIT_EMERGECONFLICT = -13, /*< Merge conflicts prevented operation */
GIT_ELOCKED = -14, /*< Lock file prevented operation */
GIT_EMODIFIED = -15, /*< Reference value does not match expected */
GIT_PASSTHROUGH = -30, /*< Internal only */
GIT_ITEROVER = -31, /*< Signals end of iteration with iterator */
......
......@@ -182,7 +182,8 @@ GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo,
* @param signature The identity that will used to populate the reflog entry
* @param log_message The one line long message to be appended to the reflog
* @param old_id The old value which the reference should have
* @return 0 on success, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
* @return 0 on success, GIT_EMODIFIED if the value of the reference
* has changed, GIT_EEXISTS, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_reference_create_matching(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force, const git_signature *signature, const char *log_message, const git_oid *old_id);
......@@ -308,7 +309,8 @@ GIT_EXTERN(int) git_reference_symbolic_set_target(
* @param id The new target OID for the reference
* @param signature The identity that will used to populate the reflog entry
* @param log_message The one line long message to be appended to the reflog
* @return 0 or an error code
* @return 0 on success, GIT_EMODIFIED if the value of the reference
* has changed, or an error code
*/
GIT_EXTERN(int) git_reference_set_target(
git_reference **out,
......
......@@ -941,7 +941,7 @@ static int refdb_fs_backend__write(
refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
git_filebuf file = GIT_FILEBUF_INIT;
git_reference *old_ref;
int error;
int error = 0;
assert(backend);
......@@ -961,12 +961,14 @@ static int refdb_fs_backend__write(
if (old_ref->type == GIT_REF_SYMBOLIC) {
giterr_set(GITERR_REFERENCE, "cannot compare id to symbolic reference target");
error = -1;
goto on_error;
}
/* Finally we can compare the ids */
if (git_oid_cmp(old_id, &old_ref->target.oid)) {
giterr_set(GITERR_REFERENCE, "old reference value does not match");
error = GIT_EMODIFIED;
goto on_error;
}
}
......@@ -982,7 +984,7 @@ static int refdb_fs_backend__write(
on_error:
git_filebuf_cleanup(&file);
git_reference_free(old_ref);
return -1;
return error;
}
static int refdb_fs_backend__delete(
......
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