summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commit.h3
-rw-r--r--src/git/tag.h28
-rw-r--r--src/repository.c3
-rw-r--r--src/tag.c78
-rw-r--r--src/tag.h1
5 files changed, 107 insertions, 6 deletions
diff --git a/src/commit.h b/src/commit.h
index 8039930f7..39a7a52ff 100644
--- a/src/commit.h
+++ b/src/commit.h
@@ -32,12 +32,13 @@ void git_commit__free(git_commit *c);
int git_commit__parse(git_commit *commit);
int git_commit__parse_full(git_commit *commit);
int git_commit__parse_buffer(git_commit *commit, void *data, size_t len, unsigned int parse_flags);
-void git_commit__mark_uninteresting(git_commit *commit);
int git_commit__writeback(git_commit *commit, git_odb_source *src);
int git__parse_oid(git_oid *oid, char **buffer_out, const char *buffer_end, const char *header);
int git__parse_person(git_person *person, char **buffer_out, const char *buffer_end, const char *header);
+int git__write_oid(git_odb_source *src, const char *header, const git_oid *oid);
+int git__write_person(git_odb_source *src, const char *header, const git_person *person);
#endif
diff --git a/src/git/tag.h b/src/git/tag.h
index 33e3d6f26..aa232128b 100644
--- a/src/git/tag.h
+++ b/src/git/tag.h
@@ -83,6 +83,34 @@ GIT_EXTERN(const git_person *) git_tag_tagger(git_tag *t);
*/
GIT_EXTERN(const char *) git_tag_message(git_tag *t);
+/**
+ * Set the target of a tag (i.e. the object that the tag points to)
+ * @param tag The tag to modify
+ * @param target the new tagged target
+ */
+GIT_EXTERN(void) git_tag_set_target(git_tag *tag, git_object *target);
+
+/**
+ * Set the name of a tag
+ * @param tag The tag to modify
+ * @param name the new name for the tag
+ */
+GIT_EXTERN(void) git_tag_set_name(git_tag *tag, const char *name);
+
+/**
+ * Set the tagger of a tag
+ * @param tag The tag to modify
+ * @param tagger the new tagger for the tag
+ */
+GIT_EXTERN(void) git_tag_set_tagger(git_tag *tag, const git_person *tagger);
+
+/**
+ * Set the message of a tag
+ * @param tag The tag to modify
+ * @param message the new tagger for the tag
+ */
+GIT_EXTERN(void) git_tag_set_message(git_tag *tag, const char *message);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/repository.c b/src/repository.c
index 22f2bba40..19f1c4e53 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -274,6 +274,9 @@ int git_object_write(git_object *object)
break;
case GIT_OBJ_TAG:
+ error = git_tag__writeback((git_tag *)object, source);
+ break;
+
default:
error = GIT_ERROR;
break;
diff --git a/src/tag.c b/src/tag.c
index 734556ba7..4a79fbd49 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -53,26 +53,79 @@ const git_object *git_tag_target(git_tag *t)
return t->target;
}
+void git_tag_set_target(git_tag *tag, git_object *target)
+{
+ assert(tag && target);
+
+ tag->object.modified = 1;
+ tag->target = target;
+ tag->type = git_object_type(target);
+}
+
git_otype git_tag_type(git_tag *t)
{
return t->type;
}
+void git_tag_set_type(git_tag *tag, git_otype type)
+{
+ assert(tag);
+
+ tag->object.modified = 1;
+ tag->type = type;
+}
+
const char *git_tag_name(git_tag *t)
{
return t->tag_name;
}
+void git_tag_set_name(git_tag *tag, const char *name)
+{
+ assert(tag && name);
+
+ /* TODO: sanity check? no newlines in message */
+ tag->object.modified = 1;
+
+ if (tag->tag_name)
+ free(tag->tag_name);
+
+ tag->tag_name = git__strdup(name);
+}
+
const git_person *git_tag_tagger(git_tag *t)
{
return t->tagger;
}
+void git_tag_set_tagger(git_tag *tag, const git_person *tagger)
+{
+ assert(tag && tagger);
+
+ tag->object.modified = 1;
+ if (tag->tagger == NULL)
+ tag->tagger = git__malloc(sizeof(git_person));
+
+ memcpy(tag->tagger, tagger, sizeof(git_person));
+}
+
const char *git_tag_message(git_tag *t)
{
return t->message;
}
+void git_tag_set_message(git_tag *tag, const char *message)
+{
+ assert(tag && message);
+
+ tag->object.modified = 1;
+
+ if (tag->message)
+ free(tag->message);
+
+ tag->message = git__strdup(message);
+}
+
static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
{
static const char *tag_types[] = {
@@ -115,10 +168,8 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
tag->target =
git_repository_lookup(tag->object.repo, &target_oid, tag->type);
- /* FIXME: is the tag file really corrupted if the tagged object
- * cannot be found on the database? */
- /* if (tag->target == NULL)
- return GIT_EOBJCORRUPTED; */
+ if (tag->target == NULL)
+ return GIT_EOBJCORRUPTED;
if (buffer + 4 >= buffer_end)
return GIT_EOBJCORRUPTED;
@@ -150,7 +201,7 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
if (git__parse_person(tag->tagger, &buffer, buffer_end, "tagger ") != 0)
return GIT_EOBJCORRUPTED;
- text_len = buffer_end - buffer;
+ text_len = buffer_end - ++buffer;
if (tag->message != NULL)
free(tag->message);
@@ -162,6 +213,23 @@ static int parse_tag_buffer(git_tag *tag, char *buffer, const char *buffer_end)
return 0;
}
+int git_tag__writeback(git_tag *tag, git_odb_source *src)
+{
+ if (tag->target == NULL || tag->tag_name == NULL || tag->tagger == NULL)
+ return GIT_ERROR;
+
+ git__write_oid(src, "object", git_object_id(tag->target));
+ git__source_printf(src, "type %s\n", git_obj_type_to_string(tag->type));
+ git__source_printf(src, "tag %s\n", tag->tag_name);
+ git__write_person(src, "tagger", tag->tagger);
+
+ if (tag->message != NULL)
+ git__source_printf(src, "\n%s", tag->message);
+
+ return GIT_SUCCESS;
+}
+
+
int git_tag__parse(git_tag *tag)
{
int error = 0;
diff --git a/src/tag.h b/src/tag.h
index 6d9cd8232..fbf520868 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -16,5 +16,6 @@ struct git_tag {
void git_tag__free(git_tag *tag);
int git_tag__parse(git_tag *tag);
+int git_tag__writeback(git_tag *tag, git_odb_source *src);
#endif