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.
This commit is contained in:
Carlos Martín Nieto 2014-01-29 14:07:18 +01:00
parent 5d96fe8828
commit fc4728e3e2
3 changed files with 9 additions and 4 deletions

View File

@ -40,6 +40,7 @@ typedef enum {
GIT_EINVALIDSPEC = -12, /*< Name/ref spec was not in a valid format */ GIT_EINVALIDSPEC = -12, /*< Name/ref spec was not in a valid format */
GIT_EMERGECONFLICT = -13, /*< Merge conflicts prevented operation */ GIT_EMERGECONFLICT = -13, /*< Merge conflicts prevented operation */
GIT_ELOCKED = -14, /*< Lock file prevented operation */ GIT_ELOCKED = -14, /*< Lock file prevented operation */
GIT_EMODIFIED = -15, /*< Reference value does not match expected */
GIT_PASSTHROUGH = -30, /*< Internal only */ GIT_PASSTHROUGH = -30, /*< Internal only */
GIT_ITEROVER = -31, /*< Signals end of iteration with iterator */ GIT_ITEROVER = -31, /*< Signals end of iteration with iterator */

View File

@ -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 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 log_message The one line long message to be appended to the reflog
* @param old_id The old value which the reference should have * @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); 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 id The new target OID for the reference
* @param signature The identity that will used to populate the reflog entry * @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 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_EXTERN(int) git_reference_set_target(
git_reference **out, git_reference **out,

View File

@ -941,7 +941,7 @@ static int refdb_fs_backend__write(
refdb_fs_backend *backend = (refdb_fs_backend *)_backend; refdb_fs_backend *backend = (refdb_fs_backend *)_backend;
git_filebuf file = GIT_FILEBUF_INIT; git_filebuf file = GIT_FILEBUF_INIT;
git_reference *old_ref; git_reference *old_ref;
int error; int error = 0;
assert(backend); assert(backend);
@ -961,12 +961,14 @@ static int refdb_fs_backend__write(
if (old_ref->type == GIT_REF_SYMBOLIC) { if (old_ref->type == GIT_REF_SYMBOLIC) {
giterr_set(GITERR_REFERENCE, "cannot compare id to symbolic reference target"); giterr_set(GITERR_REFERENCE, "cannot compare id to symbolic reference target");
error = -1;
goto on_error; goto on_error;
} }
/* Finally we can compare the ids */ /* Finally we can compare the ids */
if (git_oid_cmp(old_id, &old_ref->target.oid)) { if (git_oid_cmp(old_id, &old_ref->target.oid)) {
giterr_set(GITERR_REFERENCE, "old reference value does not match"); giterr_set(GITERR_REFERENCE, "old reference value does not match");
error = GIT_EMODIFIED;
goto on_error; goto on_error;
} }
} }
@ -982,7 +984,7 @@ static int refdb_fs_backend__write(
on_error: on_error:
git_filebuf_cleanup(&file); git_filebuf_cleanup(&file);
git_reference_free(old_ref); git_reference_free(old_ref);
return -1; return error;
} }
static int refdb_fs_backend__delete( static int refdb_fs_backend__delete(