diff options
author | Nico von Geyso <Nico.Geyso@FU-Berlin.de> | 2013-03-06 16:43:21 +0100 |
---|---|---|
committer | Nico von Geyso <Nico.Geyso@FU-Berlin.de> | 2013-03-06 17:01:33 +0100 |
commit | 6edb427b7615207142e10a228164d6a019045126 (patch) | |
tree | df37c3e13d447f8fd5ee33198cbe7921439c4f2d | |
parent | d1bcc1a8744343253df569ae4798302c1ff796e7 (diff) | |
download | libgit2-6edb427b7615207142e10a228164d6a019045126.tar.gz |
basic note iterator implementation
* git_note_iterator_new() - create a new note iterator
* git_note_next() - retrieves the next item of the iterator
-rw-r--r-- | include/git2/notes.h | 39 | ||||
-rw-r--r-- | src/notes.c | 68 | ||||
-rw-r--r-- | src/notes.h | 3 | ||||
-rw-r--r-- | tests-clar/notes/notes.c | 67 |
4 files changed, 167 insertions, 10 deletions
diff --git a/include/git2/notes.h b/include/git2/notes.h index c51d3732a..466f0a894 100644 --- a/include/git2/notes.h +++ b/include/git2/notes.h @@ -30,6 +30,45 @@ typedef int (*git_note_foreach_cb)( const git_oid *blob_id, const git_oid *annotated_object_id, void *payload); /** + * note iterator + */ +typedef struct git_iterator git_iterator; + +/** + * Creates a new iterator for notes + * + * The iterator must be freed manually by the user. + * + * @param out pointer to the iterator + * @param repo repository where to look up the note + * @param notes_ref canonical name of the reference to use (optional); defaults to + * "refs/notes/commits" + * + * @return 0 or an error code + */ +GIT_EXTERN(int) git_note_iterator_new( + git_iterator **out, + git_repository *repo, + const char *notes_ref); + +/** + * Next iteration step for note iteration + * + * The notes must not be freed manually by the user. + * + * @param it pointer to the iterator + * @param note_id id of blob containing the message + * @param annotated_id id of the git object being annotated + * + * @return 0, GIT_ITEROVER or an error code + */ +GIT_EXTERN(int) git_note_next( + git_oid* note_id, + git_oid* annotated_id, + git_iterator *it); + + +/** * Read the note for an object * * The note must be freed manually by the user. diff --git a/src/notes.c b/src/notes.c index f5537db3f..d7462d017 100644 --- a/src/notes.c +++ b/src/notes.c @@ -531,14 +531,12 @@ void git_note_free(git_note *note) static int process_entry_path( const char* entry_path, - const git_oid *note_oid, - git_note_foreach_cb note_cb, - void *payload) + git_oid *annotated_object_id +) { int error = -1; size_t i = 0, j = 0, len; git_buf buf = GIT_BUF_INIT; - git_oid annotated_object_id; if ((error = git_buf_puts(&buf, entry_path)) < 0) goto cleanup; @@ -571,12 +569,9 @@ static int process_entry_path( goto cleanup; } - if ((error = git_oid_fromstr(&annotated_object_id, buf.ptr)) < 0) + if ((error = git_oid_fromstr(annotated_object_id, buf.ptr)) < 0) goto cleanup; - if (note_cb(note_oid, &annotated_object_id, payload)) - error = GIT_EUSER; - cleanup: git_buf_free(&buf); return error; @@ -592,6 +587,7 @@ int git_note_foreach( git_iterator *iter = NULL; git_tree *tree = NULL; git_commit *commit = NULL; + git_oid annotated_object_id; const git_index_entry *item; if (!(error = retrieve_note_tree_and_commit( @@ -600,7 +596,10 @@ int git_note_foreach( error = git_iterator_current(iter, &item); while (!error && item) { - error = process_entry_path(item->path, &item->oid, note_cb, payload); + error = process_entry_path(item->path, &annotated_object_id); + + if (note_cb(&item->oid, &annotated_object_id, payload)) + error = GIT_EUSER; if (!error) error = git_iterator_advance(iter, &item); @@ -612,3 +611,54 @@ int git_note_foreach( return error; } + +int git_note_iterator_new( + git_iterator **it, + git_repository *repo, + const char *notes_ref +) +{ + int error; + git_commit *commit = NULL; + git_tree *tree = NULL; + + error = retrieve_note_tree_and_commit(&tree, &commit, repo, ¬es_ref); + if (!error) { + *it = (git_iterator *)git__malloc(sizeof(git_iterator)); + GITERR_CHECK_ALLOC(*it); + + error = git_iterator_for_tree(it, tree); + if (error) + git_iterator_free(*it); + } + + git_tree_free(tree); + git_commit_free(commit); + + return error; +} + +int git_note_next( + git_oid* note_id, + git_oid* annotated_id, + git_iterator *it +) +{ + int error; + const git_index_entry *item; + + error = git_iterator_current(it, &item); + if (!error && item) { + git_oid_cpy(note_id, &item->oid); + + error = process_entry_path(item->path, annotated_id); + + if (!error) + error = git_iterator_advance(it, NULL); + } + + if (!error && !item) + error = GIT_ITEROVER; + + return error; +} diff --git a/src/notes.h b/src/notes.h index 2f119e3c3..70d5e13fc 100644 --- a/src/notes.h +++ b/src/notes.h @@ -10,6 +10,9 @@ #include "common.h" #include "git2/oid.h" +#include "git2/types.h" + +#include "iterator.h" #define GIT_NOTES_DEFAULT_REF "refs/notes/commits" diff --git a/tests-clar/notes/notes.c b/tests-clar/notes/notes.c index ee0b6c2f8..ea810670f 100644 --- a/tests-clar/notes/notes.c +++ b/tests-clar/notes/notes.c @@ -40,7 +40,9 @@ static void create_note(git_oid *note_oid, const char *canonical_namespace, cons static struct { const char *note_sha; const char *annotated_object_sha; -} list_expectations[] = { +} + +list_expectations[] = { { "1c73b1f51762155d357bcd1fd4f2c409ef80065b", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045" }, { "1c73b1f51762155d357bcd1fd4f2c409ef80065b", "9fd738e8f7967c078dceed8190330fc8648ee56a" }, { "257b43746b6b46caa4aa788376c647cce0a33e2b", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750" }, @@ -317,3 +319,66 @@ void test_notes_notes__removing_a_note_which_doesnt_exists_returns_ENOTFOUND(voi cl_git_fail(error); cl_assert_equal_i(GIT_ENOTFOUND, error); } + +void test_notes_notes__can_iterate_default_namespace(void) +{ + git_iterator *iter; + git_note *note; + git_oid note_id, annotated_id; + git_oid note_created[2]; + const char* note_message[] = { + "I decorate a65f\n", + "I decorate c478\n" + }; + int i; + + create_note(¬e_created[0], "refs/notes/commits", + "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", note_message[0]); + create_note(¬e_created[1], "refs/notes/commits", + "c47800c7266a2be04c571c04d5a6614691ea99bd", note_message[1]); + + cl_git_pass(git_note_iterator_new(&iter, _repo, NULL)); + + for (i = 0; git_note_next(¬e_id, &annotated_id, iter) != GIT_ITEROVER; ++i) + { + cl_git_pass(git_note_read(¬e, _repo, NULL, &annotated_id)); + cl_assert_equal_s(git_note_message(note), note_message[i]); + } + + cl_assert(i == 2); +} + +void test_notes_notes__can_iterate_custom_namespace(void) +{ + git_iterator *iter; + git_note *note; + git_oid note_id, annotated_id; + git_oid note_created[2]; + const char* note_message[] = { + "I decorate a65f\n", + "I decorate c478\n" + }; + int i; + + create_note(¬e_created[0], "refs/notes/beer", + "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", note_message[0]); + create_note(¬e_created[1], "refs/notes/beer", + "c47800c7266a2be04c571c04d5a6614691ea99bd", note_message[1]); + + cl_git_pass(git_note_iterator_new(&iter, _repo, "refs/notes/beer")); + + for (i = 0; git_note_next(¬e_id, &annotated_id, iter) != GIT_ITEROVER; ++i) + { + cl_git_pass(git_note_read(¬e, _repo, "refs/notes/beer", &annotated_id)); + cl_assert_equal_s(git_note_message(note), note_message[i]); + } + + cl_assert(i == 2); +} + +void test_notes_notes__empty_iterate(void) +{ + git_iterator *iter; + + cl_git_fail(git_note_iterator_new(&iter, _repo, "refs/notes/commits")); +} |