Merge branch 'parse-tag-buffer' of https://github.com/carlosmn/libgit2 into development
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
diff --git a/include/git2/tag.h b/include/git2/tag.h
index ee92cd5..c47e341 100644
--- a/include/git2/tag.h
+++ b/include/git2/tag.h
@@ -188,6 +188,20 @@ GIT_EXTERN(int) git_tag_create_o(
const git_signature *tagger,
const char *message);
+/**
+ * Create a new tag in the repository from a buffer
+ *
+ * @param oid Pointer where to store the OID of the newly created tag
+ *
+ * @param repo Repository where to store the tag
+ *
+ * @param buffer Raw tag data
+ */
+GIT_EXTERN(int) git_tag_create_frombuffer(
+ git_oid *oid,
+ git_repository *repo,
+ const char *buffer);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/tag.c b/src/tag.c
index 7baabab..a688577 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -142,7 +142,7 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
tag->tagger = git__malloc(sizeof(git_signature));
if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ")) != 0)
- return error;
+ goto cleanup;
text_len = buffer_end - ++buffer;
@@ -151,6 +151,14 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
tag->message[text_len] = '\0';
return GIT_SUCCESS;
+
+ cleanup:
+ if(tag->tag_name)
+ free(tag->tag_name);
+ if(tag->tagger)
+ git_signature_free(tag->tagger);
+
+ return error;
}
int git_tag_create_o(
@@ -233,6 +241,43 @@ int git_tag_create(
return error;
}
+int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *buffer)
+{
+ git_tag tag;
+ int error;
+ char *buf;
+ git_object *obj;
+
+ assert(oid && buffer);
+
+ memset(&tag, 0, sizeof(tag));
+
+ buf = strdup(buffer);
+ if(buf == NULL)
+ return GIT_ENOMEM;
+
+ if((error = parse_tag_buffer(&tag, buf, buf + strlen(buf))) < 0)
+ goto exit_freebuf;
+
+ error = git_object_lookup(&obj, repo, &tag.target, tag.type);
+ if(error < 0)
+ goto exit_freetag;
+
+ error = git_tag_create_o(oid, repo, tag.tag_name, obj,
+ tag.tagger, tag.message);
+
+ git_object_close(obj);
+
+ exit_freetag:
+ git_signature_free(tag.tagger);
+ free(tag.tag_name);
+ free(tag.message);
+ exit_freebuf:
+ free(buf);
+
+ return error;
+}
+
int git_tag__parse(git_tag *tag, git_odb_object *obj)
{