Commit 9a02725d by Richard Ipsum

notes: Add git_note_commit_remove

This also adds tests for this function.
parent 7096bf1e
......@@ -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
......
......@@ -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, &notes_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, &notes_commit);
cleanup:
git_tree_free(tree);
return error;
}
int git_note_default_ref(git_buf *out, git_repository *repo)
{
char *default_ref;
......
......@@ -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(&note_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(&note, _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(&notes_commit_oid, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0));
git_commit_lookup(&existing_notes_commit, _repo, &notes_commit_oid);
cl_assert(existing_notes_commit);
cl_git_pass(git_note_commit_remove(&notes_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", &notes_commit_oid, 0, NULL));
cl_git_fail(git_note_read(&note, _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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment