]> git.proxmox.com Git - libgit2.git/commitdiff
Merge pull request #216 from glesserd/development
authorVicent Martí <tanoku@gmail.com>
Wed, 8 Jun 2011 15:11:26 +0000 (08:11 -0700)
committerVicent Martí <tanoku@gmail.com>
Wed, 8 Jun 2011 15:11:26 +0000 (08:11 -0700)
git_tag_create{,_o,_frombuffer} correction and improvement

include/git2/tag.h
src/tag.c

index 3f82ce46bc4ee6689ff8df32bae2fc25ea0498c1..49836a1f5a19cd86068544a2cf54dbfac66b0929 100644 (file)
@@ -152,7 +152,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
  *
index 905d129efe69363f4dc7366b09aa2d1c77ac1d9b..10ed9c0c2b41a16c8f466c78fbac6c862defbfe0 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -180,6 +180,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,
@@ -202,34 +242,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)
-                       return GIT_EEXISTS;     
-               should_update_ref = 1;
-               
-               /* Fall trough */
-
-       case GIT_ENOTFOUND: 
-               break;
-
-       default:
-               return error == GIT_SUCCESS ? GIT_SUCCESS : 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");
+        *   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;
+               }
        }
 
        type_str = git_object_type2string(target_type);
@@ -283,20 +307,49 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
 {
        git_tag tag;
        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));
-
+       
+       /* 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);
-
+       
+       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");
 }