Commit d8ad64d3669182d368120a9b8db1147421498e22

Vicent Marti 2011-04-02T12:28:35

Merge branch 'parse-tag-buffer' of https://github.com/carlosmn/libgit2 into development

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)
 {