diff options
| author | Richard Ipsum <richardipsum@fastmail.co.uk> | 2017-03-15 18:17:42 +0000 |
|---|---|---|
| committer | Richard Ipsum <richardipsum@fastmail.co.uk> | 2017-10-07 00:43:29 +0100 |
| commit | 9a02725d11acb302b0d9ef7013ae81ffd59525c7 (patch) | |
| tree | 8bf93af54d61b0bf45df4447c9b6b4c343b19cfd | |
| parent | 7096bf1ef6b5c7c5659ea9d8c66c85bda8ef20db (diff) | |
| download | libgit2-9a02725d11acb302b0d9ef7013ae81ffd59525c7.tar.gz | |
notes: Add git_note_commit_remove
This also adds tests for this function.
| -rw-r--r-- | include/git2/notes.h | 26 | ||||
| -rw-r--r-- | src/notes.c | 37 | ||||
| -rw-r--r-- | tests/notes/notes.c | 44 |
3 files changed, 105 insertions, 2 deletions
diff --git a/include/git2/notes.h b/include/git2/notes.h index c6b2d9594..f3cde4ebf 100644 --- a/include/git2/notes.h +++ b/include/git2/notes.h @@ -223,6 +223,32 @@ GIT_EXTERN(int) git_note_remove( const git_oid *oid); /** + * Remove the note for an object + * + * @param notes_commit_out pointer to store the new notes commit (optional); + * NULL in case of error. + * When removing a note a new tree containing all notes + * sans the note to be removed is created and a new commit + * pointing to that tree is also created. + * In the case where the resulting tree is an empty tree + * a new commit pointing to this empty tree will be returned. + * @param repo repository where the note lives + * @param notes_commit a pointer to the notes commit object + * @param author signature of the notes commit author + * @param committer signature of the notes commit committer + * @param oid OID of the git object to remove the note from + * + * @return 0 or an error code + */ +GIT_EXTERN(int) git_note_commit_remove( + git_oid *notes_commit_out, + git_repository *repo, + git_commit *notes_commit, + const git_signature *author, + const git_signature *committer, + const git_oid *oid); + +/** * Free a git_note object * * @param note git_note object diff --git a/src/notes.c b/src/notes.c index 35ba93d7c..9aef8fcac 100644 --- a/src/notes.c +++ b/src/notes.c @@ -369,7 +369,9 @@ cleanup: return error; } -static int note_remove(git_repository *repo, +static int note_remove( + git_oid *notes_commit_out, + git_repository *repo, const git_signature *author, const git_signature *committer, const char *notes_ref, git_tree *tree, const char *target, git_commit **parents) @@ -389,6 +391,12 @@ static int note_remove(git_repository *repo, *parents == NULL ? 0 : 1, (const git_commit **) parents); + if (error < 0) + goto cleanup; + + if (notes_commit_out) + git_oid_cpy(notes_commit_out, &oid); + cleanup: git_tree_free(tree_after_removal); return error; @@ -564,7 +572,7 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, if (!(error = retrieve_note_tree_and_commit( &tree, &commit, ¬es_ref, repo, notes_ref_in))) - error = note_remove( + error = note_remove(NULL, repo, author, committer, notes_ref, tree, target, &commit); git__free(notes_ref); @@ -574,6 +582,31 @@ int git_note_remove(git_repository *repo, const char *notes_ref_in, return error; } +int git_note_commit_remove( + git_oid *notes_commit_out, + git_repository *repo, + git_commit *notes_commit, + const git_signature *author, + const git_signature *committer, + const git_oid *oid) +{ + int error; + git_tree *tree = NULL; + char target[GIT_OID_HEXSZ + 1]; + + git_oid_tostr(target, sizeof(target), oid); + + if ((error = git_commit_tree(&tree, notes_commit)) < 0) + goto cleanup; + + error = note_remove(notes_commit_out, + repo, author, committer, NULL, tree, target, ¬es_commit); + +cleanup: + git_tree_free(tree); + return error; +} + int git_note_default_ref(git_buf *out, git_repository *repo) { char *default_ref; diff --git a/tests/notes/notes.c b/tests/notes/notes.c index ebc62fd41..dcf607d00 100644 --- a/tests/notes/notes.c +++ b/tests/notes/notes.c @@ -460,6 +460,50 @@ void test_notes_notes__can_read_a_note_in_an_existing_fanout(void) git_note_free(note); } +/* Can remove a note */ +void test_notes_notes__can_remove_a_note(void) +{ + git_oid note_oid, target_oid; + git_note *note; + + create_note(¬e_oid, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 4a20\n"); + + cl_git_pass(git_oid_fromstr(&target_oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + cl_git_pass(git_note_remove(_repo, "refs/notes/i-can-see-dead-notes", _sig, _sig, &target_oid)); + + cl_git_fail(git_note_read(¬e, _repo, "refs/notes/i-can-see-dead-notes", &target_oid)); +} + +/* Can remove a note from a commit */ +void test_notes_notes__can_remove_a_note_from_commit(void) +{ + git_oid oid, notes_commit_oid; + git_note *note = NULL; + git_commit *existing_notes_commit; + git_reference *ref; + + cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045")); + + cl_git_pass(git_note_commit_create(¬es_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0)); + + git_commit_lookup(&existing_notes_commit, _repo, ¬es_commit_oid); + + cl_assert(existing_notes_commit); + + cl_git_pass(git_note_commit_remove(¬es_commit_oid, _repo, existing_notes_commit, _sig, _sig, &oid)); + + /* remove_from_commit will not update any ref, + * so we must manually create the ref, that points to the commit */ + cl_git_pass(git_reference_create(&ref, _repo, "refs/notes/i-can-see-dead-notes", ¬es_commit_oid, 0, NULL)); + + cl_git_fail(git_note_read(¬e, _repo, "refs/notes/i-can-see-dead-notes", &oid)); + + git_commit_free(existing_notes_commit); + git_reference_free(ref); + git_note_free(note); +} + + void test_notes_notes__can_remove_a_note_in_an_existing_fanout(void) { git_oid target_oid; |
