Commit 60bee89d4697832f88c484f0c236e7f25c3d62fe

Richard Ipsum 2017-03-19T18:34:07

notes: Add git_note_commit_iterator_new This also adds tests for this function.

diff --git a/include/git2/notes.h b/include/git2/notes.h
index f3cde4e..853e5de 100644
--- a/include/git2/notes.h
+++ b/include/git2/notes.h
@@ -52,6 +52,20 @@ GIT_EXTERN(int) git_note_iterator_new(
 	const char *notes_ref);
 
 /**
+ * Creates a new iterator for notes from a commit
+ *
+ * The iterator must be freed manually by the user.
+ *
+ * @param out pointer to the iterator
+ * @param notes_commit a pointer to the notes commit object
+ *
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_note_commit_iterator_new(
+	git_note_iterator **out,
+	git_commit *notes_commit);
+
+/**
  * Frees an git_note_iterator
  *
  * @param it pointer to the iterator
diff --git a/src/notes.c b/src/notes.c
index 9aef8fc..68486c9 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -766,6 +766,25 @@ cleanup:
 	return error;
 }
 
+int git_note_commit_iterator_new(
+	git_note_iterator **it,
+	git_commit *notes_commit)
+{
+	int error;
+	git_tree *tree;
+
+	if ((error = git_commit_tree(&tree, notes_commit)) < 0)
+		goto cleanup;
+
+	if ((error = git_iterator_for_tree(it, tree, NULL)) < 0)
+		git_iterator_free(*it);
+
+cleanup:
+	git_tree_free(tree);
+
+	return error;
+}
+
 int git_note_next(
 	git_oid* note_id,
 	git_oid* annotated_id,
diff --git a/tests/notes/notes.c b/tests/notes/notes.c
index dcf607d..dc7fdea 100644
--- a/tests/notes/notes.c
+++ b/tests/notes/notes.c
@@ -594,3 +594,46 @@ void test_notes_notes__empty_iterate(void)
 
 	cl_git_fail(git_note_iterator_new(&iter, _repo, "refs/notes/commits"));
 }
+
+void test_notes_notes__iterate_from_commit(void)
+{
+	git_note_iterator *iter;
+	git_note *note;
+	git_oid note_id, annotated_id;
+	git_oid oids[2];
+	git_oid notes_commit_oids[2];
+	git_commit *notes_commits[2];
+	const char* note_message[] = {
+		"I decorate a65f\n",
+		"I decorate c478\n"
+	};
+	int i, err;
+
+	cl_git_pass(git_oid_fromstr(&(oids[0]), "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
+	cl_git_pass(git_oid_fromstr(&(oids[1]), "c47800c7266a2be04c571c04d5a6614691ea99bd"));
+
+	cl_git_pass(git_note_commit_create(&notes_commit_oids[0], NULL, _repo, NULL, _sig, _sig, &(oids[0]), note_message[0], 0));
+
+	git_commit_lookup(&notes_commits[0], _repo, &notes_commit_oids[0]);
+	cl_assert(notes_commits[0]);
+
+	cl_git_pass(git_note_commit_create(&notes_commit_oids[1], NULL, _repo, notes_commits[0], _sig, _sig, &(oids[1]), note_message[1], 0));
+
+	git_commit_lookup(&notes_commits[1], _repo, &notes_commit_oids[1]);
+	cl_assert(notes_commits[1]);
+
+	cl_git_pass(git_note_commit_iterator_new(&iter, notes_commits[1]));
+
+	for (i = 0; (err = git_note_next(&note_id, &annotated_id, iter)) >= 0; ++i) {
+		cl_git_pass(git_note_commit_read(&note, _repo, notes_commits[1], &annotated_id));
+		cl_assert_equal_s(git_note_message(note), note_message[i]);
+		git_note_free(note);
+	}
+
+	cl_assert_equal_i(GIT_ITEROVER, err);
+	cl_assert_equal_i(2, i);
+
+	git_note_iterator_free(iter);
+	git_commit_free(notes_commits[0]);
+	git_commit_free(notes_commits[1]);
+}