Line Flow Count Block(s) Source
1 - /*
2 - * Copyright (C) the libgit2 contributors. All rights reserved.
3 - *
4 - * This file is part of libgit2, distributed under the GNU GPL v2 with
5 - * a Linking Exception. For full terms see the included COPYING file.
6 - */
7 -
8 - #include "notes.h"
9 -
10 - #include "git2.h"
11 - #include "refs.h"
12 - #include "config.h"
13 - #include "iterator.h"
14 - #include "signature.h"
15 - #include "blob.h"
16 -
17 58 2 static int note_error_notfound(void)
18 - {
19 58 2 git_error_set(GIT_ERROR_INVALID, "note could not be found");
20 58 3 return GIT_ENOTFOUND;
21 - }
22 -
23 114 2 static int find_subtree_in_current_level(
24 - git_tree **out,
25 - git_repository *repo,
26 - git_tree *parent,
27 - const char *annotated_object_sha,
28 - int fanout)
29 - {
30 - size_t i;
31 - const git_tree_entry *entry;
32 -
33 114 2 *out = NULL;
34 -
35 114 2 if (parent == NULL)
36 24 3 return note_error_notfound();
37 -
38 297 4,21-23 for (i = 0; i < git_tree_entrycount(parent); i++) {
39 263 5 entry = git_tree_entry_byindex(parent, i);
40 -
41 263 6-8 if (!git__ishex(git_tree_entry_name(entry)))
42 ##### 9 continue;
43 -
44 263 10,11 if (S_ISDIR(git_tree_entry_filemode(entry))
45 34 12,13 && strlen(git_tree_entry_name(entry)) == 2
46 34 14,15 && !strncmp(git_tree_entry_name(entry), annotated_object_sha + fanout, 2))
47 12 16,17 return git_tree_lookup(out, repo, git_tree_entry_id(entry));
48 -
49 - /* Not a DIR, so do we have an already existing blob? */
50 251 18,19 if (!strcmp(git_tree_entry_name(entry), annotated_object_sha + fanout))
51 44 20 return GIT_EEXISTS;
52 - }
53 -
54 34 24 return note_error_notfound();
55 - }
56 -
57 46 2 static int find_subtree_r(git_tree **out, git_tree *root,
58 - git_repository *repo, const char *target, int *fanout)
59 - {
60 - int error;
61 46 2 git_tree *subtree = NULL;
62 -
63 46 2 *out = NULL;
64 -
65 46 2 error = find_subtree_in_current_level(&subtree, repo, root, target, *fanout);
66 46 3 if (error == GIT_EEXISTS)
67 35 4,5 return git_tree_lookup(out, repo, git_tree_id(root));
68 -
69 11 6 if (error < 0)
70 6 7 return error;
71 -
72 5 8 *fanout += 2;
73 5 8 error = find_subtree_r(out, subtree, repo, target, fanout);
74 5 9 git_tree_free(subtree);
75 -
76 5 10 return error;
77 - }
78 -
79 35 2 static int find_blob(git_oid *blob, git_tree *tree, const char *target)
80 - {
81 - size_t i;
82 - const git_tree_entry *entry;
83 -
84 100 2,9-11 for (i=0; i<git_tree_entrycount(tree); i++) {
85 100 3 entry = git_tree_entry_byindex(tree, i);
86 -
87 100 4,5 if (!strcmp(git_tree_entry_name(entry), target)) {
88 - /* found matching note object - return */
89 -
90 35 6,7 git_oid_cpy(blob, git_tree_entry_id(entry));
91 35 8 return 0;
92 - }
93 - }
94 -
95 ##### 12 return note_error_notfound();
96 - }
97 -
98 63 2 static int tree_write(
99 - git_tree **out,
100 - git_repository *repo,
101 - git_tree *source_tree,
102 - const git_oid *object_oid,
103 - const char *treeentry_name,
104 - unsigned int attributes)
105 - {
106 - int error;
107 63 2 git_treebuilder *tb = NULL;
108 - const git_tree_entry *entry;
109 - git_oid tree_oid;
110 -
111 63 2,3 if ((error = git_treebuilder_new(&tb, repo, source_tree)) < 0)
112 ##### 4 goto cleanup;
113 -
114 63 5 if (object_oid) {
115 58 6,7 if ((error = git_treebuilder_insert(
116 - &entry, tb, treeentry_name, object_oid, attributes)) < 0)
117 ##### 8 goto cleanup;
118 - } else {
119 5 9,10 if ((error = git_treebuilder_remove(tb, treeentry_name)) < 0)
120 ##### 11 goto cleanup;
121 - }
122 -
123 63 12,13 if ((error = git_treebuilder_write(&tree_oid, tb)) < 0)
124 ##### 14 goto cleanup;
125 -
126 63 15 error = git_tree_lookup(out, repo, &tree_oid);
127 -
128 - cleanup:
129 63 16 git_treebuilder_free(tb);
130 63 17 return error;
131 - }
132 -
133 68 2 static int manipulate_note_in_tree_r(
134 - git_tree **out,
135 - git_repository *repo,
136 - git_tree *parent,
137 - git_oid *note_oid,
138 - const char *annotated_object_sha,
139 - int fanout,
140 - int (*note_exists_cb)(
141 - git_tree **out,
142 - git_repository *repo,
143 - git_tree *parent,
144 - git_oid *note_oid,
145 - const char *annotated_object_sha,
146 - int fanout,
147 - int current_error),
148 - int (*note_notfound_cb)(
149 - git_tree **out,
150 - git_repository *repo,
151 - git_tree *parent,
152 - git_oid *note_oid,
153 - const char *annotated_object_sha,
154 - int fanout,
155 - int current_error))
156 - {
157 - int error;
158 68 2 git_tree *subtree = NULL, *new = NULL;
159 - char subtree_name[3];
160 -
161 68 2 error = find_subtree_in_current_level(
162 - &subtree, repo, parent, annotated_object_sha, fanout);
163 -
164 68 3 if (error == GIT_EEXISTS) {
165 9 4 error = note_exists_cb(
166 - out, repo, parent, note_oid, annotated_object_sha, fanout, error);
167 9 5 goto cleanup;
168 - }
169 -
170 59 6 if (error == GIT_ENOTFOUND) {
171 52 7 error = note_notfound_cb(
172 - out, repo, parent, note_oid, annotated_object_sha, fanout, error);
173 52 8 goto cleanup;
174 - }
175 -
176 7 9 if (error < 0)
177 ##### 10 goto cleanup;
178 -
179 - /* An existing fanout has been found, let's dig deeper */
180 7 11 error = manipulate_note_in_tree_r(
181 - &new, repo, subtree, note_oid, annotated_object_sha,
182 - fanout + 2, note_exists_cb, note_notfound_cb);
183 -
184 7 12 if (error < 0)
185 2 13 goto cleanup;
186 -
187 5 14 strncpy(subtree_name, annotated_object_sha + fanout, 2);
188 5 14 subtree_name[2] = '\0';
189 -
190 5 14,15 error = tree_write(out, repo, parent, git_tree_id(new),
191 - subtree_name, GIT_FILEMODE_TREE);
192 -
193 -
194 - cleanup:
195 68 16 git_tree_free(new);
196 68 17 git_tree_free(subtree);
197 68 18 return error;
198 - }
199 -
200 5 2 static int remove_note_in_tree_eexists_cb(
201 - git_tree **out,
202 - git_repository *repo,
203 - git_tree *parent,
204 - git_oid *note_oid,
205 - const char *annotated_object_sha,
206 - int fanout,
207 - int current_error)
208 - {
209 - GIT_UNUSED(note_oid);
210 - GIT_UNUSED(current_error);
211 -
212 5 2 return tree_write(out, repo, parent, NULL, annotated_object_sha + fanout, 0);
213 - }
214 -
215 1 2 static int remove_note_in_tree_enotfound_cb(
216 - git_tree **out,
217 - git_repository *repo,
218 - git_tree *parent,
219 - git_oid *note_oid,
220 - const char *annotated_object_sha,
221 - int fanout,
222 - int current_error)
223 - {
224 - GIT_UNUSED(out);
225 - GIT_UNUSED(repo);
226 - GIT_UNUSED(parent);
227 - GIT_UNUSED(note_oid);
228 - GIT_UNUSED(fanout);
229 -
230 1 2 git_error_set(GIT_ERROR_REPOSITORY, "object '%s' has no note", annotated_object_sha);
231 1 3 return current_error;
232 - }
233 -
234 2 2 static int insert_note_in_tree_eexists_cb(git_tree **out,
235 - git_repository *repo,
236 - git_tree *parent,
237 - git_oid *note_oid,
238 - const char *annotated_object_sha,
239 - int fanout,
240 - int current_error)
241 - {
242 - GIT_UNUSED(out);
243 - GIT_UNUSED(repo);
244 - GIT_UNUSED(parent);
245 - GIT_UNUSED(note_oid);
246 - GIT_UNUSED(fanout);
247 -
248 2 2 git_error_set(GIT_ERROR_REPOSITORY, "note for '%s' exists already", annotated_object_sha);
249 2 3 return current_error;
250 - }
251 -
252 53 2 static int insert_note_in_tree_enotfound_cb(git_tree **out,
253 - git_repository *repo,
254 - git_tree *parent,
255 - git_oid *note_oid,
256 - const char *annotated_object_sha,
257 - int fanout,
258 - int current_error)
259 - {
260 - GIT_UNUSED(current_error);
261 -
262 - /* No existing fanout at this level, insert in place */
263 53 2 return tree_write(
264 - out,
265 - repo,
266 - parent,
267 - note_oid,
268 - annotated_object_sha + fanout,
269 - GIT_FILEMODE_BLOB);
270 - }
271 -
272 55 2 static int note_write(
273 - git_oid *notes_commit_out,
274 - git_oid *notes_blob_out,
275 - git_repository *repo,
276 - const git_signature *author,
277 - const git_signature *committer,
278 - const char *notes_ref,
279 - const char *note,
280 - git_tree *commit_tree,
281 - const char *target,
282 - git_commit **parents,
283 - int allow_note_overwrite)
284 - {
285 - int error;
286 - git_oid oid;
287 55 2 git_tree *tree = NULL;
288 -
289 - /* TODO: should we apply filters? */
290 - /* create note object */
291 55 2,3 if ((error = git_blob_create_from_buffer(&oid, repo, note, strlen(note))) < 0)
292 ##### 4 goto cleanup;
293 -
294 55 5-9 if ((error = manipulate_note_in_tree_r(
295 - &tree, repo, commit_tree, &oid, target, 0,
296 - allow_note_overwrite ? insert_note_in_tree_enotfound_cb : insert_note_in_tree_eexists_cb,
297 - insert_note_in_tree_enotfound_cb)) < 0)
298 2 10 goto cleanup;
299 -
300 53 11 if (notes_blob_out)
301 45 12 git_oid_cpy(notes_blob_out, &oid);
302 -
303 -
304 53 13 error = git_commit_create(&oid, repo, notes_ref, author, committer,
305 - NULL, GIT_NOTES_DEFAULT_MSG_ADD,
306 53 13 tree, *parents == NULL ? 0 : 1, (const git_commit **) parents);
307 -
308 53 14 if (notes_commit_out)
309 53 15 git_oid_cpy(notes_commit_out, &oid);
310 -
311 - cleanup:
312 55 16 git_tree_free(tree);
313 55 17 return error;
314 - }
315 -
316 35 2 static int note_new(
317 - git_note **out,
318 - git_oid *note_oid,
319 - git_commit *commit,
320 - git_blob *blob)
321 - {
322 35 2 git_note *note = NULL;
323 - git_object_size_t blobsize;
324 -
325 35 2 note = git__malloc(sizeof(git_note));
326 35 3,4 GIT_ERROR_CHECK_ALLOC(note);
327 -
328 35 5 git_oid_cpy(&note->id, note_oid);
329 -
330 35 6-8,11 if (git_signature_dup(&note->author, git_commit_author(commit)) < 0 ||
331 35 9,10 git_signature_dup(&note->committer, git_commit_committer(commit)) < 0)
332 ##### 12 return -1;
333 -
334 35 13 blobsize = git_blob_rawsize(blob);
335 35 14-17 GIT_ERROR_CHECK_BLOBSIZE(blobsize);
336 -
337 35 18,19 note->message = git__strndup(git_blob_rawcontent(blob), (size_t)blobsize);
338 35 20,21 GIT_ERROR_CHECK_ALLOC(note->message);
339 -
340 35 22 *out = note;
341 35 22 return 0;
342 - }
343 -
344 41 2 static int note_lookup(
345 - git_note **out,
346 - git_repository *repo,
347 - git_commit *commit,
348 - git_tree *tree,
349 - const char *target)
350 - {
351 41 2 int error, fanout = 0;
352 - git_oid oid;
353 41 2 git_blob *blob = NULL;
354 41 2 git_note *note = NULL;
355 41 2 git_tree *subtree = NULL;
356 -
357 41 2,3 if ((error = find_subtree_r(&subtree, tree, repo, target, &fanout)) < 0)
358 6 4 goto cleanup;
359 -
360 35 5,6 if ((error = find_blob(&oid, subtree, target + fanout)) < 0)
361 ##### 7 goto cleanup;
362 -
363 35 8,9 if ((error = git_blob_lookup(&blob, repo, &oid)) < 0)
364 ##### 10 goto cleanup;
365 -
366 35 11,12 if ((error = note_new(&note, &oid, commit, blob)) < 0)
367 ##### 13 goto cleanup;
368 -
369 35 14 *out = note;
370 -
371 - cleanup:
372 41 15 git_tree_free(subtree);
373 41 16 git_blob_free(blob);
374 41 17 return error;
375 - }
376 -
377 6 2 static int note_remove(
378 - git_oid *notes_commit_out,
379 - git_repository *repo,
380 - const git_signature *author, const git_signature *committer,
381 - const char *notes_ref, git_tree *tree,
382 - const char *target, git_commit **parents)
383 - {
384 - int error;
385 6 2 git_tree *tree_after_removal = NULL;
386 - git_oid oid;
387 -
388 6 2,3 if ((error = manipulate_note_in_tree_r(
389 - &tree_after_removal, repo, tree, NULL, target, 0,
390 - remove_note_in_tree_eexists_cb, remove_note_in_tree_enotfound_cb)) < 0)
391 1 4 goto cleanup;
392 -
393 5 5 error = git_commit_create(&oid, repo, notes_ref, author, committer,
394 - NULL, GIT_NOTES_DEFAULT_MSG_RM,
395 - tree_after_removal,
396 5 5 *parents == NULL ? 0 : 1,
397 - (const git_commit **) parents);
398 -
399 5 6 if (error < 0)
400 ##### 7 goto cleanup;
401 -
402 5 8 if (notes_commit_out)
403 5 9 git_oid_cpy(notes_commit_out, &oid);
404 -
405 - cleanup:
406 6 10 git_tree_free(tree_after_removal);
407 6 11 return error;
408 - }
409 -
410 15 2 static int note_get_default_ref(char **out, git_repository *repo)
411 - {
412 - git_config *cfg;
413 15 2 int ret = git_repository_config__weakptr(&cfg, repo);
414 -
415 15 3-5 *out = (ret != 0) ? NULL : git_config__get_string_force(
416 - cfg, "core.notesref", GIT_NOTES_DEFAULT_REF);
417 -
418 15 6 return ret;
419 - }
420 -
421 97 2 static int normalize_namespace(char **out, git_repository *repo, const char *notes_ref)
422 - {
423 97 2 if (notes_ref) {
424 85 3 *out = git__strdup(notes_ref);
425 85 4,5 GIT_ERROR_CHECK_ALLOC(*out);
426 85 6 return 0;
427 - }
428 -
429 12 7 return note_get_default_ref(out, repo);
430 - }
431 -
432 97 2 static int retrieve_note_commit(
433 - git_commit **commit_out,
434 - char **notes_ref_out,
435 - git_repository *repo,
436 - const char *notes_ref)
437 - {
438 - int error;
439 - git_oid oid;
440 -
441 97 2,3 if ((error = normalize_namespace(notes_ref_out, repo, notes_ref)) < 0)
442 ##### 4 return error;
443 -
444 97 5,6 if ((error = git_reference_name_to_id(&oid, repo, *notes_ref_out)) < 0)
445 20 7 return error;
446 -
447 77 8,9 if (git_commit_lookup(commit_out, repo, &oid) < 0)
448 ##### 10 return error;
449 -
450 77 11 return 0;
451 - }
452 -
453 41 2 int git_note_commit_read(
454 - git_note **out,
455 - git_repository *repo,
456 - git_commit *notes_commit,
457 - const git_oid *oid)
458 - {
459 - int error;
460 41 2 git_tree *tree = NULL;
461 - char target[GIT_OID_HEXSZ + 1];
462 -
463 41 2 git_oid_tostr(target, sizeof(target), oid);
464 -
465 41 3,4 if ((error = git_commit_tree(&tree, notes_commit)) < 0)
466 ##### 5 goto cleanup;
467 -
468 41 6 error = note_lookup(out, repo, notes_commit, tree, target);
469 -
470 - cleanup:
471 41 7 git_tree_free(tree);
472 41 8 return error;
473 - }
474 -
475 37 2 int git_note_read(git_note **out, git_repository *repo,
476 - const char *notes_ref_in, const git_oid *oid)
477 - {
478 - int error;
479 37 2 char *notes_ref = NULL;
480 37 2 git_commit *commit = NULL;
481 -
482 37 2 error = retrieve_note_commit(&commit, &notes_ref, repo, notes_ref_in);
483 -
484 37 3 if (error < 0)
485 ##### 4 goto cleanup;
486 -
487 37 5 error = git_note_commit_read(out, repo, commit, oid);
488 -
489 - cleanup:
490 37 6 git__free(notes_ref);
491 37 7 git_commit_free(commit);
492 37 8 return error;
493 - }
494 -
495 55 2 int git_note_commit_create(
496 - git_oid *notes_commit_out,
497 - git_oid *notes_blob_out,
498 - git_repository *repo,
499 - git_commit *parent,
500 - const git_signature *author,
501 - const git_signature *committer,
502 - const git_oid *oid,
503 - const char *note,
504 - int allow_note_overwrite)
505 - {
506 - int error;
507 55 2 git_tree *tree = NULL;
508 - char target[GIT_OID_HEXSZ + 1];
509 -
510 55 2 git_oid_tostr(target, sizeof(target), oid);
511 -
512 55 3-5 if (parent != NULL && (error = git_commit_tree(&tree, parent)) < 0)
513 ##### 6 goto cleanup;
514 -
515 55 7 error = note_write(notes_commit_out, notes_blob_out, repo, author,
516 - committer, NULL, note, tree, target, &parent, allow_note_overwrite);
517 -
518 55 8 if (error < 0)
519 2 9 goto cleanup;
520 -
521 - cleanup:
522 55 10 git_tree_free(tree);
523 55 11 return error;
524 - }
525 -
526 47 2 int git_note_create(
527 - git_oid *out,
528 - git_repository *repo,
529 - const char *notes_ref_in,
530 - const git_signature *author,
531 - const git_signature *committer,
532 - const git_oid *oid,
533 - const char *note,
534 - int allow_note_overwrite)
535 - {
536 - int error;
537 47 2 char *notes_ref = NULL;
538 47 2 git_commit *existing_notes_commit = NULL;
539 47 2 git_reference *ref = NULL;
540 - git_oid notes_blob_oid, notes_commit_oid;
541 -
542 47 2 error = retrieve_note_commit(&existing_notes_commit, &notes_ref,
543 - repo, notes_ref_in);
544 -
545 47 3,4 if (error < 0 && error != GIT_ENOTFOUND)
546 ##### 5 goto cleanup;
547 -
548 47 6 error = git_note_commit_create(&notes_commit_oid,
549 - &notes_blob_oid,
550 - repo, existing_notes_commit, author,
551 - committer, oid, note,
552 - allow_note_overwrite);
553 47 7 if (error < 0)
554 2 8 goto cleanup;
555 -
556 45 9 error = git_reference_create(&ref, repo, notes_ref,
557 - &notes_commit_oid, 1, NULL);
558 -
559 45 10 if (out != NULL)
560 45 11 git_oid_cpy(out, &notes_blob_oid);
561 -
562 - cleanup:
563 47 12 git__free(notes_ref);
564 47 13 git_commit_free(existing_notes_commit);
565 47 14 git_reference_free(ref);
566 47 15 return error;
567 - }
568 -
569 6 2 int git_note_commit_remove(
570 - git_oid *notes_commit_out,
571 - git_repository *repo,
572 - git_commit *notes_commit,
573 - const git_signature *author,
574 - const git_signature *committer,
575 - const git_oid *oid)
576 - {
577 - int error;
578 6 2 git_tree *tree = NULL;
579 - char target[GIT_OID_HEXSZ + 1];
580 -
581 6 2 git_oid_tostr(target, sizeof(target), oid);
582 -
583 6 3,4 if ((error = git_commit_tree(&tree, notes_commit)) < 0)
584 ##### 5 goto cleanup;
585 -
586 6 6 error = note_remove(notes_commit_out,
587 - repo, author, committer, NULL, tree, target, &notes_commit);
588 -
589 - cleanup:
590 6 7 git_tree_free(tree);
591 6 8 return error;
592 - }
593 -
594 4 2 int git_note_remove(git_repository *repo, const char *notes_ref_in,
595 - const git_signature *author, const git_signature *committer,
596 - const git_oid *oid)
597 - {
598 - int error;
599 4 2 char *notes_ref_target = NULL;
600 4 2 git_commit *existing_notes_commit = NULL;
601 - git_oid new_notes_commit;
602 4 2 git_reference *notes_ref = NULL;
603 -
604 4 2 error = retrieve_note_commit(&existing_notes_commit, &notes_ref_target,
605 - repo, notes_ref_in);
606 -
607 4 3 if (error < 0)
608 ##### 4 goto cleanup;
609 -
610 4 5 error = git_note_commit_remove(&new_notes_commit, repo,
611 - existing_notes_commit, author, committer, oid);
612 4 6 if (error < 0)
613 1 7 goto cleanup;
614 -
615 3 8 error = git_reference_create(&notes_ref, repo, notes_ref_target,
616 - &new_notes_commit, 1, NULL);
617 -
618 - cleanup:
619 4 9 git__free(notes_ref_target);
620 4 10 git_reference_free(notes_ref);
621 4 11 git_commit_free(existing_notes_commit);
622 4 12 return error;
623 - }
624 -
625 3 2 int git_note_default_ref(git_buf *out, git_repository *repo)
626 - {
627 - char *default_ref;
628 - int error;
629 -
630 3 2-4 assert(out && repo);
631 -
632 3 5 git_buf_sanitize(out);
633 -
634 3 6,7 if ((error = note_get_default_ref(&default_ref, repo)) < 0)
635 ##### 8 return error;
636 -
637 3 9 git_buf_attach(out, default_ref, strlen(default_ref));
638 3 10 return 0;
639 - }
640 -
641 ##### 2 const git_signature *git_note_committer(const git_note *note)
642 - {
643 ##### 2,3 assert(note);
644 ##### 4 return note->committer;
645 - }
646 -
647 2 2 const git_signature *git_note_author(const git_note *note)
648 - {
649 2 2,3 assert(note);
650 2 4 return note->author;
651 - }
652 -
653 24 2 const char * git_note_message(const git_note *note)
654 - {
655 24 2,3 assert(note);
656 24 4 return note->message;
657 - }
658 -
659 8 2 const git_oid * git_note_id(const git_note *note)
660 - {
661 8 2,3 assert(note);
662 8 4 return &note->id;
663 - }
664 -
665 38 2 void git_note_free(git_note *note)
666 - {
667 38 2 if (note == NULL)
668 38 3,8 return;
669 -
670 35 4 git_signature_free(note->committer);
671 35 5 git_signature_free(note->author);
672 35 6 git__free(note->message);
673 35 7 git__free(note);
674 - }
675 -
676 17 2 static int process_entry_path(
677 - const char* entry_path,
678 - git_oid *annotated_object_id)
679 - {
680 17 2 int error = 0;
681 17 2 size_t i = 0, j = 0, len;
682 17 2 git_buf buf = GIT_BUF_INIT;
683 -
684 17 2,3 if ((error = git_buf_puts(&buf, entry_path)) < 0)
685 ##### 4 goto cleanup;
686 -
687 17 5 len = git_buf_len(&buf);
688 -
689 697 6,15 while (i < len) {
690 680 7 if (buf.ptr[i] == '/') {
691 ##### 8 i++;
692 ##### 8 continue;
693 - }
694 -
695 680 9,10 if (git__fromhex(buf.ptr[i]) < 0) {
696 - /* This is not a note entry */
697 ##### 11 goto cleanup;
698 - }
699 -
700 680 12 if (i != j)
701 ##### 13 buf.ptr[j] = buf.ptr[i];
702 -
703 680 14 i++;
704 680 14 j++;
705 - }
706 -
707 17 16 buf.ptr[j] = '\0';
708 17 16 buf.size = j;
709 -
710 17 16 if (j != GIT_OID_HEXSZ) {
711 - /* This is not a note entry */
712 ##### 17 goto cleanup;
713 - }
714 -
715 17 18 error = git_oid_fromstr(annotated_object_id, buf.ptr);
716 -
717 - cleanup:
718 17 19 git_buf_dispose(&buf);
719 17 20 return error;
720 - }
721 -
722 6 2 int git_note_foreach(
723 - git_repository *repo,
724 - const char *notes_ref,
725 - git_note_foreach_cb note_cb,
726 - void *payload)
727 - {
728 - int error;
729 6 2 git_note_iterator *iter = NULL;
730 - git_oid note_id, annotated_id;
731 -
732 6 2,3 if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0)
733 1 4 return error;
734 -
735 15 5,10,11 while (!(error = git_note_next(&note_id, &annotated_id, iter))) {
736 11 6,7 if ((error = note_cb(&note_id, &annotated_id, payload)) != 0) {
737 1 8 git_error_set_after_callback(error);
738 1 9 break;
739 - }
740 - }
741 -
742 5 12 if (error == GIT_ITEROVER)
743 4 13 error = 0;
744 -
745 5 14 git_note_iterator_free(iter);
746 5 15 return error;
747 - }
748 -
749 8 2 void git_note_iterator_free(git_note_iterator *it)
750 - {
751 8 2 if (it == NULL)
752 8 3,5 return;
753 -
754 8 4 git_iterator_free(it);
755 - }
756 -
757 8 2 int git_note_commit_iterator_new(
758 - git_note_iterator **it,
759 - git_commit *notes_commit)
760 - {
761 - int error;
762 - git_tree *tree;
763 -
764 8 2,3 if ((error = git_commit_tree(&tree, notes_commit)) < 0)
765 ##### 4 goto cleanup;
766 -
767 8 5,6 if ((error = git_iterator_for_tree(it, tree, NULL)) < 0)
768 ##### 7 git_iterator_free(*it);
769 -
770 - cleanup:
771 8 8 git_tree_free(tree);
772 -
773 8 9 return error;
774 - }
775 -
776 9 2 int git_note_iterator_new(
777 - git_note_iterator **it,
778 - git_repository *repo,
779 - const char *notes_ref_in)
780 - {
781 - int error;
782 9 2 git_commit *commit = NULL;
783 - char *notes_ref;
784 -
785 9 2 error = retrieve_note_commit(&commit, &notes_ref, repo, notes_ref_in);
786 9 3 if (error < 0)
787 2 4 goto cleanup;
788 -
789 7 5 error = git_note_commit_iterator_new(it, commit);
790 -
791 - cleanup:
792 9 6 git__free(notes_ref);
793 9 7 git_commit_free(commit);
794 -
795 9 8 return error;
796 - }
797 -
798 24 2 int git_note_next(
799 - git_oid* note_id,
800 - git_oid* annotated_id,
801 - git_note_iterator *it)
802 - {
803 - int error;
804 - const git_index_entry *item;
805 -
806 24 2,3 if ((error = git_iterator_current(&item, it)) < 0)
807 7 4 return error;
808 -
809 17 5 git_oid_cpy(note_id, &item->id);
810 -
811 17 6,7 if ((error = process_entry_path(item->path, annotated_id)) < 0)
812 ##### 8 return error;
813 -
814 17 9-11 if ((error = git_iterator_advance(NULL, it)) < 0 && error != GIT_ITEROVER)
815 ##### 12 return error;
816 -
817 17 13 return 0;
818 - }