Commit 15b0bed2ba170526969348170d6f5e0d2ee16d7b

Brodie Rao 2011-08-11T16:12:29

tag: allow the tagger field to be missing when parsing tags Instead of bailing out with an error, this sets tagger to NULL when the field is missing from the object. This makes it possible to inspect tags like this one: http://git.kernel.org/?p=git/git.git;a=tag;h=f25a265a342aed6041ab0cc484224d9ca54b6f41

diff --git a/src/tag.c b/src/tag.c
index 08ebb71..ba75104 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -122,12 +122,16 @@ static int parse_tag_buffer(git_tag *tag, const char *buffer, const char *buffer
 
 	buffer = search + 1;
 
-	tag->tagger = git__malloc(sizeof(git_signature));
-	if (tag->tagger == NULL)
-		return GIT_ENOMEM;
-
-	if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n')) != 0)
-		return git__rethrow(error, "Failed to parse tag");
+	tag->tagger = NULL;
+	if (*buffer != '\n') {
+		tag->tagger = git__malloc(sizeof(git_signature));
+		if (tag->tagger == NULL)
+			return GIT_ENOMEM;
+
+		if ((error = git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n') != 0)) {
+			return git__rethrow(error, "Failed to parse tag");
+		}
+	}
 
 	if( *buffer != '\n' )
 		return git__throw(GIT_EOBJCORRUPTED, "Failed to parse tag. No new line before message");
diff --git a/tests/t08-tag.c b/tests/t08-tag.c
index 079a9e0..216fb9d 100644
--- a/tests/t08-tag.c
+++ b/tests/t08-tag.c
@@ -31,6 +31,7 @@ static const char *tag1_id = "b25fa35b38051e4ae45d4222e795f9df2e43f1d1";
 static const char *tag2_id = "7b4384978d2493e851f9cca7858815fac9b10980";
 static const char *tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
 static const char *bad_tag_id = "eda9f45a2a98d4c17a09d681d88569fa4ea91755";
+static const char *badly_tagged_commit = "e90810b8df3e80c413d903f631643c716887138d";
 
 BEGIN_TEST(read0, "read and parse a tag from the repository")
 	git_repository *repo;
@@ -112,13 +113,28 @@ END_TEST
 BEGIN_TEST(read3, "read and parse a tag without a tagger field")
 	git_repository *repo;
 	git_tag *bad_tag;
-	git_oid id;
+	git_commit *commit;
+	git_oid id, id_commit;
 
 	must_pass(git_repository_open(&repo, BAD_TAG_REPOSITORY_FOLDER));
 
 	git_oid_fromstr(&id, bad_tag_id);
+	git_oid_fromstr(&id_commit, badly_tagged_commit);
+
+	must_pass(git_tag_lookup(&bad_tag, repo, &id));
+	must_be_true(bad_tag != NULL);
+
+	must_be_true(strcmp(git_tag_name(bad_tag), "e90810b") == 0);
+	must_be_true(git_oid_cmp(&id, git_tag_id(bad_tag)) == 0);
+	must_be_true(bad_tag->tagger == NULL);
+
+	must_pass(git_tag_target((git_object **)&commit, bad_tag));
+	must_be_true(commit != NULL);
+
+	must_be_true(git_oid_cmp(&id_commit, git_commit_id(commit)) == 0);
 
-	must_fail(git_tag_lookup(&bad_tag, repo, &id));
+	git_tag_close(bad_tag);
+	git_commit_close(commit);
 
 	git_repository_free(repo);
 END_TEST