From 448c4d012b9237541377d8d82684644c8a331902 Mon Sep 17 00:00:00 2001 From: David Glesser Date: Mon, 30 May 2011 08:46:48 +0200 Subject: [PATCH 1/6] Add an error message when a tag already exists. Before this commit, no message is shown when doing a git_lasterror(). --- src/tag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tag.c b/src/tag.c index 0f5ddf699..4132eef3b 100644 --- a/src/tag.c +++ b/src/tag.c @@ -206,7 +206,7 @@ static int tag_create( switch (error) { case GIT_SUCCESS: if (!allow_ref_overwrite) - return GIT_EEXISTS; + return git__throw(GIT_EEXISTS, "Tag already exists"); should_update_ref = 1; /* Fall trough */ @@ -215,7 +215,7 @@ static int tag_create( break; default: - return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to create tag"); + return git__rethrow(error, "Failed to create tag"); } if (!git_odb_exists(repo->db, target)) From 23123151e035f3565f7c9c93c1bbdb56c7cd6914 Mon Sep 17 00:00:00 2001 From: David Glesser Date: Mon, 30 May 2011 09:03:55 +0200 Subject: [PATCH 2/6] Set the oid when a tag already exists. When a tag already exists, it can be useful to directly have the oid of the existed tag, just after trying to add it. --- include/git2/tag.h | 4 +++- src/tag.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/git2/tag.h b/include/git2/tag.h index 3fc6b4499..086e4a6ca 100644 --- a/include/git2/tag.h +++ b/include/git2/tag.h @@ -135,7 +135,9 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *t); * Create a new tag in the repository from an OID * * @param oid Pointer where to store the OID of the - * newly created tag + * newly created tag. If the tag already exists, this parameter + * will be the oid of the existed tag, and the function will + * return a GIT_EEXISTS error code. * * @param repo Repository where to store the tag * diff --git a/src/tag.c b/src/tag.c index 4132eef3b..6ae51b6f7 100644 --- a/src/tag.c +++ b/src/tag.c @@ -205,8 +205,10 @@ static int tag_create( switch (error) { case GIT_SUCCESS: - if (!allow_ref_overwrite) + if (!allow_ref_overwrite) { + git_oid_cpy(oid, git_reference_oid(new_ref)); return git__throw(GIT_EEXISTS, "Tag already exists"); + } should_update_ref = 1; /* Fall trough */ From 3ecdf9106596906e74c54e1e956c289fdea89b88 Mon Sep 17 00:00:00 2001 From: David Glesser Date: Tue, 31 May 2011 11:53:09 +0200 Subject: [PATCH 3/6] Modify create_tag : verifications are now done in an another function This commit create a function called tag_valid_in_odb which validate a tag before its creation. This function will be needed by my next commit. --- src/tag.c | 74 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/src/tag.c b/src/tag.c index 6ae51b6f7..6a70efd83 100644 --- a/src/tag.c +++ b/src/tag.c @@ -177,6 +177,46 @@ static int retreive_tag_reference(git_reference **tag_reference_out, char *ref_n return GIT_SUCCESS; } +/* tag_reference_out will contain the reference of the tag if exists, otherwise NULL */ +static int tag_valid_in_odb( + git_reference **tag_reference_out, + char *ref_name_out, + const git_oid *target, + git_otype target_type, + git_repository *repo, + const char *tag_name) { + + int error; + + *tag_reference_out = NULL; + + + error = retreive_tag_reference(tag_reference_out, ref_name_out, repo, tag_name); + + switch (error) { + case GIT_SUCCESS: + /* Fall trough */ + case GIT_ENOTFOUND: + break; + + default: + return git__rethrow(error, "Failed to create tag"); + } + + if (!git_odb_exists(repo->db, target)) + return git__throw(GIT_ENOTFOUND, "Failed to create tag. Object to tag doesn't exist"); + + /* Try to find out what the type is */ + if (target_type == GIT_OBJ_ANY) { + size_t _unused; + error = git_odb_read_header(&_unused, &target_type, repo->db, target); + if (error < GIT_SUCCESS) + return git__rethrow(error, "Failed to create tag"); + } + + return GIT_SUCCESS; +} + static int tag_create( git_oid *oid, git_repository *repo, @@ -199,36 +239,18 @@ static int tag_create( int type_str_len, tag_name_len, tagger_str_len, message_len; int error, should_update_ref = 0; + if ((error = tag_valid_in_odb(&new_ref, ref_name, target, target_type, repo, tag_name)) < GIT_SUCCESS) + return git__rethrow(error, "Failed to create tag"); + /** Ensure the tag name doesn't conflict with an already existing - reference unless overwriting has explictly been requested **/ - error = retreive_tag_reference(&new_ref, ref_name, repo, tag_name); - - switch (error) { - case GIT_SUCCESS: - if (!allow_ref_overwrite) { + * reference unless overwriting has explictly been requested **/ + if(new_ref != NULL) { + if(!allow_ref_overwrite) { git_oid_cpy(oid, git_reference_oid(new_ref)); return git__throw(GIT_EEXISTS, "Tag already exists"); + } else { + should_update_ref = 1; } - should_update_ref = 1; - - /* Fall trough */ - - case GIT_ENOTFOUND: - break; - - default: - return git__rethrow(error, "Failed to create tag"); - } - - if (!git_odb_exists(repo->db, target)) - return git__throw(GIT_ENOTFOUND, "Failed to create tag. Object to tag doesn't exist"); - - /* Try to find out what the type is */ - if (target_type == GIT_OBJ_ANY) { - size_t _unused; - error = git_odb_read_header(&_unused, &target_type, repo->db, target); - if (error < GIT_SUCCESS) - return git__rethrow(error, "Failed to create tag"); } type_str = git_object_type2string(target_type); From ac4fcf173d0d6797a71c24de5f3bbeb1770e2888 Mon Sep 17 00:00:00 2001 From: David Glesser Date: Tue, 31 May 2011 11:56:39 +0200 Subject: [PATCH 4/6] Modify git_tag_create_frombuffer: the buffer is not modified when writen to the odb libgit2 has now the same behaviour of git when adding a tag with a buffer. --- src/tag.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/tag.c b/src/tag.c index 6a70efd83..8cae17a42 100644 --- a/src/tag.c +++ b/src/tag.c @@ -304,20 +304,49 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu { git_tag tag; int error; - + git_odb_stream *stream; + assert(oid && buffer); - + memset(&tag, 0, sizeof(tag)); - + + /* validate the buffer */ + if ((error = parse_tag_buffer(&tag, buffer, buffer + strlen(buffer))) < GIT_SUCCESS) return git__rethrow(error, "Failed to create tag"); - - error = git_tag_create(oid, repo, tag.tag_name, &tag.target, tag.type, tag.tagger, tag.message); - + + git_reference *new_ref; + char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; + + if ((error = tag_valid_in_odb(&new_ref, ref_name, &tag.target, tag.type, repo, tag.tag_name)) < GIT_SUCCESS) + return git__rethrow(error, "Failed to create tag"); + + if(new_ref != NULL) { + git_oid_cpy(oid, git_reference_oid(new_ref)); + return git__throw(GIT_EEXISTS, "Tag already exists"); + } + + + /* write the buffer */ + + if ((error = git_odb_open_wstream(&stream, repo->db, strlen(buffer), GIT_OBJ_TAG)) < GIT_SUCCESS) + return git__rethrow(error, "Failed to create tag"); + + stream->write(stream, buffer, strlen(buffer)); + + error = stream->finalize_write(oid, stream); + stream->free(stream); + + if (error < GIT_SUCCESS) + return git__rethrow(error, "Failed to create tag"); + + + error = git_reference_create_oid(&new_ref, repo, ref_name, oid); + git_signature_free(tag.tagger); free(tag.tag_name); free(tag.message); - + return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to create tag"); } From f4c925c51449f5e9b141c4f07c7d61212e1b0a4a Mon Sep 17 00:00:00 2001 From: David Glesser Date: Sat, 4 Jun 2011 16:09:19 +0200 Subject: [PATCH 5/6] Change a dirty indentation --- include/git2/tag.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/git2/tag.h b/include/git2/tag.h index 086e4a6ca..bc05a0c1f 100644 --- a/include/git2/tag.h +++ b/include/git2/tag.h @@ -135,7 +135,7 @@ GIT_EXTERN(const char *) git_tag_message(git_tag *t); * Create a new tag in the repository from an OID * * @param oid Pointer where to store the OID of the - * newly created tag. If the tag already exists, this parameter + * newly created tag. If the tag already exists, this parameter * will be the oid of the existed tag, and the function will * return a GIT_EEXISTS error code. * From 1c68d27d07a03b874e98f0c8eccfc7602f948567 Mon Sep 17 00:00:00 2001 From: David Glesser Date: Tue, 7 Jun 2011 10:15:31 +0200 Subject: [PATCH 6/6] Fix the error pointed out by tanoku. Now the code shoulb be c89. --- src/tag.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tag.c b/src/tag.c index 8cae17a42..b00c92520 100644 --- a/src/tag.c +++ b/src/tag.c @@ -306,6 +306,9 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu int error; git_odb_stream *stream; + git_reference *new_ref; + char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; + assert(oid && buffer); memset(&tag, 0, sizeof(tag)); @@ -315,9 +318,6 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu if ((error = parse_tag_buffer(&tag, buffer, buffer + strlen(buffer))) < GIT_SUCCESS) return git__rethrow(error, "Failed to create tag"); - git_reference *new_ref; - char ref_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; - if ((error = tag_valid_in_odb(&new_ref, ref_name, &tag.target, tag.type, repo, tag.tag_name)) < GIT_SUCCESS) return git__rethrow(error, "Failed to create tag");