Skip to content

Commit a46e743

Browse files
committed
notes: Add git_note_commit_create
This adds a new function that will allow creation of notes without necessarily updating a particular ref, the notes tree is obtained from the git_commit object parameter, a new commit object pointing to the current tip of the notes tree is optionally returned via the 'note_commit_out' parameter, optionally the blob id for the note is returned through the 'note_blob_out' object.
1 parent 5b1641f commit a46e743

File tree

3 files changed

+183
-0
lines changed

3 files changed

+183
-0
lines changed

include/git2/notes.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,36 @@ GIT_EXTERN(int) git_note_create(
153153
const char *note,
154154
int force);
155155

156+
/**
157+
* Add a note for an object from a commit
158+
*
159+
* This function will create a notes commit for a given object,
160+
* the commit is a dangling commit, no reference is created.
161+
*
162+
* @param notes_commit_out pointer to store the commit (optional);
163+
* NULL in case of error
164+
* @param notes_blob_out a point to the id of a note blob (optional)
165+
* @param repo repository where the note will live
166+
* @param parent Pointer to parent note
167+
* or NULL if this shall start a new notes tree
168+
* @param author signature of the notes commit author
169+
* @param committer signature of the notes commit committer
170+
* @param oid OID of the git object to decorate
171+
* @param note Content of the note to add for object oid
172+
* @param allow_note_overwrite Overwrite existing note
173+
*
174+
* @return 0 or an error code
175+
*/
176+
GIT_EXTERN(int) git_note_commit_create(
177+
git_oid *notes_commit_out,
178+
git_oid *notes_blob_out,
179+
git_repository *repo,
180+
git_commit *parent,
181+
const git_signature *author,
182+
const git_signature *committer,
183+
const git_oid *oid,
184+
const char *note,
185+
int allow_note_overwrite);
156186

157187
/**
158188
* Remove the note for an object

src/notes.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,37 @@ int git_note_create(
497497
return error;
498498
}
499499

500+
int git_note_commit_create(
501+
git_oid *notes_commit_out,
502+
git_oid *notes_blob_out,
503+
git_repository *repo,
504+
git_commit *parent,
505+
const git_signature *author,
506+
const git_signature *committer,
507+
const git_oid *oid,
508+
const char *note,
509+
int allow_note_overwrite)
510+
{
511+
int error;
512+
git_tree *tree = NULL;
513+
char target[GIT_OID_HEXSZ + 1];
514+
515+
git_oid_tostr(target, sizeof(target), oid);
516+
517+
if (parent != NULL && (error = git_commit_tree(&tree, parent)) < 0)
518+
goto cleanup;
519+
520+
error = note_write(notes_commit_out, notes_blob_out, repo, author,
521+
committer, NULL, note, tree, target, &parent, allow_note_overwrite);
522+
523+
if (error < 0)
524+
goto cleanup;
525+
526+
cleanup:
527+
git_tree_free(tree);
528+
return error;
529+
}
530+
500531
int git_note_remove(git_repository *repo, const char *notes_ref_in,
501532
const git_signature *author, const git_signature *committer,
502533
const git_oid *oid)

tests/notes/notes.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,128 @@ static int note_list_cb(
7373
return 0;
7474
}
7575

76+
struct note_create_payload {
77+
const char *note_oid;
78+
const char *object_oid;
79+
unsigned seen;
80+
};
81+
82+
static int note_list_create_cb(
83+
const git_oid *blob_oid, const git_oid *annotated_obj_id, void *payload)
84+
{
85+
git_oid expected_note_oid, expected_target_oid;
86+
struct note_create_payload *notes = payload;
87+
size_t i;
88+
89+
for (i = 0; notes[i].note_oid != NULL; i++) {
90+
cl_git_pass(git_oid_fromstr(&expected_note_oid, notes[i].note_oid));
91+
92+
if (git_oid_cmp(&expected_note_oid, blob_oid) != 0)
93+
continue;
94+
95+
cl_git_pass(git_oid_fromstr(&expected_target_oid, notes[i].object_oid));
96+
97+
if (git_oid_cmp(&expected_target_oid, annotated_obj_id) != 0)
98+
continue;
99+
100+
notes[i].seen = 1;
101+
return 0;
102+
}
103+
104+
cl_fail("Did not see expected note");
105+
return 0;
106+
}
107+
108+
void assert_notes_seen(struct note_create_payload payload[], size_t n)
109+
{
110+
size_t seen = 0, i;
111+
112+
for (i = 0; payload[i].note_oid != NULL; i++) {
113+
if (payload[i].seen)
114+
seen++;
115+
}
116+
117+
cl_assert_equal_i(seen, n);
118+
}
119+
120+
void test_notes_notes__can_create_a_note(void)
121+
{
122+
git_oid note_oid;
123+
static struct note_create_payload can_create_a_note[] = {
124+
{ "1c9b1bc36730582a42d56eeee0dc58673d7ae869", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", 0 },
125+
{ NULL, NULL, 0 }
126+
};
127+
128+
create_note(&note_oid, "refs/notes/i-can-see-dead-notes", can_create_a_note[0].object_oid, "I decorate 4a20\n");
129+
130+
cl_git_pass(git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", note_list_create_cb, &can_create_a_note));
131+
132+
assert_notes_seen(can_create_a_note, 1);
133+
}
134+
135+
void test_notes_notes__can_create_a_note_from_commit(void)
136+
{
137+
git_oid oid;
138+
git_oid notes_commit_out;
139+
git_reference *ref;
140+
static struct note_create_payload can_create_a_note_from_commit[] = {
141+
{ "1c9b1bc36730582a42d56eeee0dc58673d7ae869", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", 0 },
142+
{ NULL, NULL, 0 }
143+
};
144+
145+
cl_git_pass(git_oid_fromstr(&oid, can_create_a_note_from_commit[0].object_oid));
146+
147+
cl_git_pass(git_note_commit_create(&notes_commit_out, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 1));
148+
149+
/* create_from_commit will not update any ref,
150+
* so we must manually create the ref, that points to the commit */
151+
cl_git_pass(git_reference_create(&ref, _repo, "refs/notes/i-can-see-dead-notes", &notes_commit_out, 0, NULL));
152+
153+
cl_git_pass(git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", note_list_create_cb, &can_create_a_note_from_commit));
154+
155+
assert_notes_seen(can_create_a_note_from_commit, 1);
156+
157+
git_reference_free(ref);
158+
}
159+
160+
161+
/* Test that we can create a note from a commit, given an existing commit */
162+
void test_notes_notes__can_create_a_note_from_commit_given_an_existing_commit(void)
163+
{
164+
git_oid oid;
165+
git_oid notes_commit_out;
166+
git_commit *existing_notes_commit = NULL;
167+
git_reference *ref;
168+
static struct note_create_payload can_create_a_note_from_commit_given_an_existing_commit[] = {
169+
{ "1c9b1bc36730582a42d56eeee0dc58673d7ae869", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", 0 },
170+
{ "1aaf94147c21f981e0a20bf57b89137c5a6aae52", "9fd738e8f7967c078dceed8190330fc8648ee56a", 0 },
171+
{ NULL, NULL, 0 }
172+
};
173+
174+
cl_git_pass(git_oid_fromstr(&oid, "4a202b346bb0fb0db7eff3cffeb3c70babbd2045"));
175+
176+
cl_git_pass(git_note_commit_create(&notes_commit_out, NULL, _repo, NULL, _sig, _sig, &oid, "I decorate 4a20\n", 0));
177+
178+
cl_git_pass(git_oid_fromstr(&oid, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
179+
180+
git_commit_lookup(&existing_notes_commit, _repo, &notes_commit_out);
181+
182+
cl_assert(existing_notes_commit);
183+
184+
cl_git_pass(git_note_commit_create(&notes_commit_out, NULL, _repo, existing_notes_commit, _sig, _sig, &oid, "I decorate 9fd7\n", 0));
185+
186+
/* create_from_commit will not update any ref,
187+
* so we must manually create the ref, that points to the commit */
188+
cl_git_pass(git_reference_create(&ref, _repo, "refs/notes/i-can-see-dead-notes", &notes_commit_out, 0, NULL));
189+
190+
cl_git_pass(git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", note_list_create_cb, &can_create_a_note_from_commit_given_an_existing_commit));
191+
192+
assert_notes_seen(can_create_a_note_from_commit_given_an_existing_commit, 2);
193+
194+
git_commit_free(existing_notes_commit);
195+
git_reference_free(ref);
196+
}
197+
76198
/*
77199
* $ git notes --ref i-can-see-dead-notes add -m "I decorate a65f" a65fedf39aefe402d3bb6e24df4d4f5fe4547750
78200
* $ git notes --ref i-can-see-dead-notes add -m "I decorate c478" c47800c7266a2be04c571c04d5a6614691ea99bd

0 commit comments

Comments
 (0)