Skip to content

Commit 9a02725

Browse files
committed
notes: Add git_note_commit_remove
This also adds tests for this function.
1 parent 7096bf1 commit 9a02725

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-2
lines changed

include/git2/notes.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,32 @@ GIT_EXTERN(int) git_note_remove(
222222
const git_signature *committer,
223223
const git_oid *oid);
224224

225+
/**
226+
* Remove the note for an object
227+
*
228+
* @param notes_commit_out pointer to store the new notes commit (optional);
229+
* NULL in case of error.
230+
* When removing a note a new tree containing all notes
231+
* sans the note to be removed is created and a new commit
232+
* pointing to that tree is also created.
233+
* In the case where the resulting tree is an empty tree
234+
* a new commit pointing to this empty tree will be returned.
235+
* @param repo repository where the note lives
236+
* @param notes_commit a pointer to the notes commit object
237+
* @param author signature of the notes commit author
238+
* @param committer signature of the notes commit committer
239+
* @param oid OID of the git object to remove the note from
240+
*
241+
* @return 0 or an error code
242+
*/
243+
GIT_EXTERN(int) git_note_commit_remove(
244+
git_oid *notes_commit_out,
245+
git_repository *repo,
246+
git_commit *notes_commit,
247+
const git_signature *author,
248+
const git_signature *committer,
249+
const git_oid *oid);
250+
225251
/**
226252
* Free a git_note object
227253
*

src/notes.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,9 @@ static int note_lookup(
369369
return error;
370370
}
371371

372-
static int note_remove(git_repository *repo,
372+
static int note_remove(
373+
git_oid *notes_commit_out,
374+
git_repository *repo,
373375
const git_signature *author, const git_signature *committer,
374376
const char *notes_ref, git_tree *tree,
375377
const char *target, git_commit **parents)
@@ -389,6 +391,12 @@ static int note_remove(git_repository *repo,
389391
*parents == NULL ? 0 : 1,
390392
(const git_commit **) parents);
391393

394+
if (error < 0)
395+
goto cleanup;
396+
397+
if (notes_commit_out)
398+
git_oid_cpy(notes_commit_out, &oid);
399+
392400
cleanup:
393401
git_tree_free(tree_after_removal);
394402
return error;
@@ -564,7 +572,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in,
564572

565573
if (!(error = retrieve_note_tree_and_commit(
566574
&tree, &commit, &notes_ref, repo, notes_ref_in)))
567-
error = note_remove(
575+
error = note_remove(NULL,
568576
repo, author, committer, notes_ref, tree, target, &commit);
569577

570578
git__free(notes_ref);
@@ -574,6 +582,31 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in,
574582
return error;
575583
}
576584

585+
int git_note_commit_remove(
586+
git_oid *notes_commit_out,
587+
git_repository *repo,
588+
git_commit *notes_commit,
589+
const git_signature *author,
590+
const git_signature *committer,
591+
const git_oid *oid)
592+
{
593+
int error;
594+
git_tree *tree = NULL;
595+
char target[GIT_OID_HEXSZ + 1];
596+
597+
git_oid_tostr(target, sizeof(target), oid);
598+
599+
if ((error = git_commit_tree(&tree, notes_commit)) < 0)
600+
goto cleanup;
601+
602+
error = note_remove(notes_commit_out,
603+
repo, author, committer, NULL, tree, target, &notes_commit);
604+
605+
cleanup:
606+
git_tree_free(tree);
607+
return error;
608+
}
609+
577610
int git_note_default_ref(git_buf *out, git_repository *repo)
578611
{
579612
char *default_ref;

tests/notes/notes.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,50 @@ void test_notes_notes__can_read_a_note_in_an_existing_fanout(void)
460460
git_note_free(note);
461461
}
462462

463+
/* Can remove a note */
464+
void test_notes_notes__can_remove_a_note(void)
465+
{
466+
git_oid note_oid, target_oid;
467+
git_note *note;
468+
469+
create_note(&note_oid, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 4a20\n");
470+
471+
cl_git_pass(git_oid_fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
472+
cl_git_pass(git_note_remove(_repo, "refs/notes/i-can-see-dead-notes", _sig, _sig, &target_oid));
473+
474+
cl_git_fail(git_note_read(&note, _repo, "refs/notes/i-can-see-dead-notes", &target_oid));
475+
}
476+
477+
/* Can remove a note from a commit */
478+
void test_notes_notes__can_remove_a_note_from_commit(void)
479+
{
480+
git_oid oid, notes_commit_oid;
481+
git_note *note = NULL;
482+
git_commit *existing_notes_commit;
483+
git_reference *ref;
484+
485+
cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
486+
487+
cl_git_pass(git_note_commit_create(&notes_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0));
488+
489+
git_commit_lookup(&existing_notes_commit, _repo, &notes_commit_oid);
490+
491+
cl_assert(existing_notes_commit);
492+
493+
cl_git_pass(git_note_commit_remove(&notes_commit_oid, _repo, existing_notes_commit, _sig, _sig, &oid));
494+
495+
/* remove_from_commit will not update any ref,
496+
* so we must manually create the ref, that points to the commit */
497+
cl_git_pass(git_reference_create(&ref, _repo, "refs/notes/i-can-see-dead-notes", &notes_commit_oid, 0, NULL));
498+
499+
cl_git_fail(git_note_read(&note, _repo, "refs/notes/i-can-see-dead-notes", &oid));
500+
501+
git_commit_free(existing_notes_commit);
502+
git_reference_free(ref);
503+
git_note_free(note);
504+
}
505+
506+
463507
void test_notes_notes__can_remove_a_note_in_an_existing_fanout(void)
464508
{
465509
git_oid target_oid;

0 commit comments

Comments
 (0)