]> git.proxmox.com Git - libgit2.git/blob - tests/commit/write.c
New upstream version 1.3.0+dfsg.1
[libgit2.git] / tests / commit / write.c
1 #include "clar_libgit2.h"
2 #include "git2/sys/commit.h"
3
4 static const char *committer_name = "Vicent Marti";
5 static const char *committer_email = "vicent@github.com";
6 static const char *commit_message = "This commit has been created in memory\n\
7 This is a commit created in memory and it will be written back to disk\n";
8 static const char *tree_id_str = "1810dff58d8a660512d4832e740f692884338ccd";
9 static const char *parent_id_str = "8496071c1b46c854b31185ea97743be6a8774479";
10 static const char *root_commit_message = "This is a root commit\n\
11 This is a root commit and should be the only one in this branch\n";
12 static const char *root_reflog_message = "commit (initial): This is a root commit \
13 This is a root commit and should be the only one in this branch";
14 static char *head_old;
15 static git_reference *head, *branch;
16 static git_commit *commit;
17
18 /* Fixture setup */
19 static git_repository *g_repo;
20 void test_commit_write__initialize(void)
21 {
22 g_repo = cl_git_sandbox_init("testrepo");
23 }
24
25 void test_commit_write__cleanup(void)
26 {
27 git_reference_free(head);
28 head = NULL;
29
30 git_reference_free(branch);
31 branch = NULL;
32
33 git_commit_free(commit);
34 commit = NULL;
35
36 git__free(head_old);
37 head_old = NULL;
38
39 cl_git_sandbox_cleanup();
40
41 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 1));
42 }
43
44
45 /* write a new commit object from memory to disk */
46 void test_commit_write__from_memory(void)
47 {
48 git_oid tree_id, parent_id, commit_id;
49 git_signature *author, *committer;
50 const git_signature *author1, *committer1;
51 git_commit *parent;
52 git_tree *tree;
53
54 git_oid_fromstr(&tree_id, tree_id_str);
55 cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
56
57 git_oid_fromstr(&parent_id, parent_id_str);
58 cl_git_pass(git_commit_lookup(&parent, g_repo, &parent_id));
59
60 /* create signatures */
61 cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60));
62 cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90));
63
64 cl_git_pass(git_commit_create_v(
65 &commit_id, /* out id */
66 g_repo,
67 NULL, /* do not update the HEAD */
68 author,
69 committer,
70 NULL,
71 commit_message,
72 tree,
73 1, parent));
74
75 git_object_free((git_object *)parent);
76 git_object_free((git_object *)tree);
77
78 git_signature_free(committer);
79 git_signature_free(author);
80
81 cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
82
83 /* Check attributes were set correctly */
84 author1 = git_commit_author(commit);
85 cl_assert(author1 != NULL);
86 cl_assert_equal_s(committer_name, author1->name);
87 cl_assert_equal_s(committer_email, author1->email);
88 cl_assert(author1->when.time == 987654321);
89 cl_assert(author1->when.offset == 90);
90
91 committer1 = git_commit_committer(commit);
92 cl_assert(committer1 != NULL);
93 cl_assert_equal_s(committer_name, committer1->name);
94 cl_assert_equal_s(committer_email, committer1->email);
95 cl_assert(committer1->when.time == 123456789);
96 cl_assert(committer1->when.offset == 60);
97
98 cl_assert_equal_s(commit_message, git_commit_message(commit));
99 }
100
101 void test_commit_write__into_buf(void)
102 {
103 git_oid tree_id;
104 git_signature *author, *committer;
105 git_tree *tree;
106 git_commit *parent;
107 git_oid parent_id;
108 git_buf commit = GIT_BUF_INIT;
109
110 git_oid_fromstr(&tree_id, tree_id_str);
111 cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
112
113 /* create signatures */
114 cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60));
115 cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90));
116
117 git_oid_fromstr(&parent_id, parent_id_str);
118 cl_git_pass(git_commit_lookup(&parent, g_repo, &parent_id));
119
120 cl_git_pass(git_commit_create_buffer(&commit, g_repo, author, committer,
121 NULL, root_commit_message, tree, 1, (const git_commit **) &parent));
122
123 cl_assert_equal_s(commit.ptr,
124 "tree 1810dff58d8a660512d4832e740f692884338ccd\n\
125 parent 8496071c1b46c854b31185ea97743be6a8774479\n\
126 author Vicent Marti <vicent@github.com> 987654321 +0130\n\
127 committer Vicent Marti <vicent@github.com> 123456789 +0100\n\
128 \n\
129 This is a root commit\n\
130 This is a root commit and should be the only one in this branch\n\
131 ");
132
133 git_buf_dispose(&commit);
134 git_tree_free(tree);
135 git_commit_free(parent);
136 git_signature_free(author);
137 git_signature_free(committer);
138 }
139
140 /* create a root commit */
141 void test_commit_write__root(void)
142 {
143 git_oid tree_id, commit_id;
144 const git_oid *branch_oid;
145 git_signature *author, *committer;
146 const char *branch_name = "refs/heads/root-commit-branch";
147 git_tree *tree;
148 git_reflog *log;
149 const git_reflog_entry *entry;
150
151 git_oid_fromstr(&tree_id, tree_id_str);
152 cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
153
154 /* create signatures */
155 cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60));
156 cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90));
157
158 /* First we need to update HEAD so it points to our non-existant branch */
159 cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
160 cl_assert(git_reference_type(head) == GIT_REFERENCE_SYMBOLIC);
161 head_old = git__strdup(git_reference_symbolic_target(head));
162 cl_assert(head_old != NULL);
163 git_reference_free(head);
164
165 cl_git_pass(git_reference_symbolic_create(&head, g_repo, "HEAD", branch_name, 1, NULL));
166
167 cl_git_pass(git_commit_create_v(
168 &commit_id, /* out id */
169 g_repo,
170 "HEAD",
171 author,
172 committer,
173 NULL,
174 root_commit_message,
175 tree,
176 0));
177
178 git_object_free((git_object *)tree);
179 git_signature_free(author);
180
181 /*
182 * The fact that creating a commit works has already been
183 * tested. Here we just make sure it's our commit and that it was
184 * written as a root commit.
185 */
186 cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
187 cl_assert(git_commit_parentcount(commit) == 0);
188 cl_git_pass(git_reference_lookup(&branch, g_repo, branch_name));
189 branch_oid = git_reference_target(branch);
190 cl_assert_equal_oid(branch_oid, &commit_id);
191 cl_assert_equal_s(root_commit_message, git_commit_message(commit));
192
193 cl_git_pass(git_reflog_read(&log, g_repo, branch_name));
194 cl_assert_equal_i(1, git_reflog_entrycount(log));
195 entry = git_reflog_entry_byindex(log, 0);
196 cl_assert_equal_s(committer->email, git_reflog_entry_committer(entry)->email);
197 cl_assert_equal_s(committer->name, git_reflog_entry_committer(entry)->name);
198 cl_assert_equal_s(root_reflog_message, git_reflog_entry_message(entry));
199
200 git_signature_free(committer);
201 git_reflog_free(log);
202 }
203
204 static int create_commit_from_ids(
205 git_oid *result,
206 const git_oid *tree_id,
207 const git_oid *parent_id)
208 {
209 git_signature *author, *committer;
210 const git_oid *parent_ids[1];
211 int ret;
212
213 cl_git_pass(git_signature_new(
214 &committer, committer_name, committer_email, 123456789, 60));
215 cl_git_pass(git_signature_new(
216 &author, committer_name, committer_email, 987654321, 90));
217
218 parent_ids[0] = parent_id;
219
220 ret = git_commit_create_from_ids(
221 result,
222 g_repo,
223 NULL,
224 author,
225 committer,
226 NULL,
227 root_commit_message,
228 tree_id,
229 1,
230 parent_ids);
231
232 git_signature_free(committer);
233 git_signature_free(author);
234
235 return ret;
236 }
237
238 void test_commit_write__can_write_invalid_objects(void)
239 {
240 git_oid expected_id, tree_id, parent_id, commit_id;
241
242 cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 0));
243
244 /* this is a valid tree and parent */
245 git_oid_fromstr(&tree_id, tree_id_str);
246 git_oid_fromstr(&parent_id, parent_id_str);
247
248 git_oid_fromstr(&expected_id, "c8571bbec3a72c4bcad31648902e5a453f1adece");
249 cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
250 cl_assert_equal_oid(&expected_id, &commit_id);
251
252 /* this is a wholly invented tree id */
253 git_oid_fromstr(&tree_id, "1234567890123456789012345678901234567890");
254 git_oid_fromstr(&parent_id, parent_id_str);
255
256 git_oid_fromstr(&expected_id, "996008340b8e68d69bf3c28d7c57fb7ec3c8e202");
257 cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
258 cl_assert_equal_oid(&expected_id, &commit_id);
259
260 /* this is a wholly invented parent id */
261 git_oid_fromstr(&tree_id, tree_id_str);
262 git_oid_fromstr(&parent_id, "1234567890123456789012345678901234567890");
263
264 git_oid_fromstr(&expected_id, "d78f660cab89d9791ca6714b57978bf2a7e709fd");
265 cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
266 cl_assert_equal_oid(&expected_id, &commit_id);
267
268 /* these are legitimate objects, but of the wrong type */
269 git_oid_fromstr(&tree_id, parent_id_str);
270 git_oid_fromstr(&parent_id, tree_id_str);
271
272 git_oid_fromstr(&expected_id, "5d80c07414e3f18792949699dfcacadf7748f361");
273 cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
274 cl_assert_equal_oid(&expected_id, &commit_id);
275 }
276
277 void test_commit_write__can_validate_objects(void)
278 {
279 git_oid tree_id, parent_id, commit_id;
280
281 /* this is a valid tree and parent */
282 git_oid_fromstr(&tree_id, tree_id_str);
283 git_oid_fromstr(&parent_id, parent_id_str);
284 cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
285
286 /* this is a wholly invented tree id */
287 git_oid_fromstr(&tree_id, "1234567890123456789012345678901234567890");
288 git_oid_fromstr(&parent_id, parent_id_str);
289 cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
290
291 /* this is a wholly invented parent id */
292 git_oid_fromstr(&tree_id, tree_id_str);
293 git_oid_fromstr(&parent_id, "1234567890123456789012345678901234567890");
294 cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
295
296 /* these are legitimate objects, but of the wrong type */
297 git_oid_fromstr(&tree_id, parent_id_str);
298 git_oid_fromstr(&parent_id, tree_id_str);
299 cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
300 }
301
302 void test_commit_write__attach_signature_checks_objects(void)
303 {
304 const char *sig = "magic word: pretty please";
305 const char *badtree = "tree 6b79e22d69bf46e289df0345a14ca059dfc9bdf6\n\
306 parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
307 author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
308 committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
309 \n\
310 a simple commit which does not work\n";
311
312 const char *badparent = "tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\
313 parent 34734e478d6cf50c27c9d69026d93974d052c454\n\
314 author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
315 committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
316 \n\
317 a simple commit which does not work\n";
318
319 git_oid id;
320
321 cl_git_fail_with(-1, git_commit_create_with_signature(&id, g_repo, badtree, sig, "magicsig"));
322 cl_git_fail_with(-1, git_commit_create_with_signature(&id, g_repo, badparent, sig, "magicsig"));
323
324 }
325
326 void test_commit_write__attach_singleline_signature(void)
327 {
328 const char *sig = "magic word: pretty please";
329
330 const char *data = "tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\
331 parent 8496071c1b46c854b31185ea97743be6a8774479\n\
332 author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
333 committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
334 \n\
335 a simple commit which works\n";
336
337 const char *complete = "tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\
338 parent 8496071c1b46c854b31185ea97743be6a8774479\n\
339 author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
340 committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
341 magicsig magic word: pretty please\n\
342 \n\
343 a simple commit which works\n";
344
345 git_oid id;
346 git_odb *odb;
347 git_odb_object *obj;
348
349 cl_git_pass(git_commit_create_with_signature(&id, g_repo, data, sig, "magicsig"));
350
351 cl_git_pass(git_repository_odb(&odb, g_repo));
352 cl_git_pass(git_odb_read(&obj, odb, &id));
353 cl_assert_equal_s(complete, git_odb_object_data(obj));
354
355 git_odb_object_free(obj);
356 git_odb_free(odb);
357 }
358
359 void test_commit_write__attach_multiline_signature(void)
360 {
361 const char *gpgsig = "-----BEGIN PGP SIGNATURE-----\n\
362 Version: GnuPG v1.4.12 (Darwin)\n\
363 \n\
364 iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al\n\
365 o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8\n\
366 JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq\n\
367 AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq\n\
368 SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW\n\
369 who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok\n\
370 6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG\n\
371 cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu\n\
372 c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9\n\
373 ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J\n\
374 7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc\n\
375 cpxtDQQMGYFpXK/71stq\n\
376 =ozeK\n\
377 -----END PGP SIGNATURE-----";
378
379 const char *data = "tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\
380 parent 8496071c1b46c854b31185ea97743be6a8774479\n\
381 author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
382 committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
383 \n\
384 a simple commit which works\n";
385
386 const char *complete = "tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\n\
387 parent 8496071c1b46c854b31185ea97743be6a8774479\n\
388 author Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
389 committer Ben Burkert <ben@benburkert.com> 1358451456 -0800\n\
390 gpgsig -----BEGIN PGP SIGNATURE-----\n\
391 Version: GnuPG v1.4.12 (Darwin)\n\
392 \n\
393 iQIcBAABAgAGBQJQ+FMIAAoJEH+LfPdZDSs1e3EQAJMjhqjWF+WkGLHju7pTw2al\n\
394 o6IoMAhv0Z/LHlWhzBd9e7JeCnanRt12bAU7yvYp9+Z+z+dbwqLwDoFp8LVuigl8\n\
395 JGLcnwiUW3rSvhjdCp9irdb4+bhKUnKUzSdsR2CK4/hC0N2i/HOvMYX+BRsvqweq\n\
396 AsAkA6dAWh+gAfedrBUkCTGhlNYoetjdakWqlGL1TiKAefEZrtA1TpPkGn92vbLq\n\
397 SphFRUY9hVn1ZBWrT3hEpvAIcZag3rTOiRVT1X1flj8B2vGCEr3RrcwOIZikpdaW\n\
398 who/X3xh/DGbI2RbuxmmJpxxP/8dsVchRJJzBwG+yhwU/iN3MlV2c5D69tls/Dok\n\
399 6VbyU4lm/ae0y3yR83D9dUlkycOnmmlBAHKIZ9qUts9X7mWJf0+yy2QxJVpjaTGG\n\
400 cmnQKKPeNIhGJk2ENnnnzjEve7L7YJQF6itbx5VCOcsGh3Ocb3YR7DMdWjt7f8pu\n\
401 c6j+q1rP7EpE2afUN/geSlp5i3x8aXZPDj67jImbVCE/Q1X9voCtyzGJH7MXR0N9\n\
402 ZpRF8yzveRfMH8bwAJjSOGAFF5XkcR/RNY95o+J+QcgBLdX48h+ZdNmUf6jqlu3J\n\
403 7KmTXXQcOVpN6dD3CmRFsbjq+x6RHwa8u1iGn+oIkX908r97ckfB/kHKH7ZdXIJc\n\
404 cpxtDQQMGYFpXK/71stq\n\
405 =ozeK\n\
406 -----END PGP SIGNATURE-----\n\
407 \n\
408 a simple commit which works\n";
409
410 git_oid one, two;
411 git_odb *odb;
412 git_odb_object *obj;
413
414 cl_git_pass(git_commit_create_with_signature(&one, g_repo, data, gpgsig, "gpgsig"));
415 cl_git_pass(git_commit_create_with_signature(&two, g_repo, data, gpgsig, NULL));
416
417 cl_assert(!git_oid_cmp(&one, &two));
418 cl_git_pass(git_repository_odb(&odb, g_repo));
419 cl_git_pass(git_odb_read(&obj, odb, &one));
420 cl_assert_equal_s(complete, git_odb_object_data(obj));
421
422 git_odb_object_free(obj);
423 git_odb_free(odb);
424 }