File Coverage

xs/Commit.xs
Criterion Covered Total %
statement 159 163 97.5
branch 62 96 64.5
condition n/a
subroutine n/a
pod n/a
total 221 259 85.3


line stmt bran cond sub pod time code
1             MODULE = Git::Raw PACKAGE = Git::Raw::Commit
2              
3             SV *
4             annotated(self)
5             SV *self
6              
7             PREINIT:
8             int rc;
9              
10             SV *repo;
11             AnnotatedCommit commit;
12             Repository repo_ptr;
13              
14             CODE:
15 8           repo = GIT_SV_TO_MAGIC(self);
16 8 50         repo_ptr = INT2PTR(Repository, SvIV((SV *) repo));
17              
18 8           rc = git_annotated_commit_lookup(&commit,
19             repo_ptr -> repository,
20 8           git_commit_id(GIT_SV_TO_PTR(Commit, self))
21             );
22 8           git_check_error(rc);
23              
24 8           GIT_NEW_OBJ_WITH_MAGIC(
25             RETVAL, "Git::Raw::AnnotatedCommit",
26             commit, repo
27             );
28              
29             OUTPUT: RETVAL
30              
31             SV *
32             create(class, repo, msg, author, committer, parents, tree, ...)
33             SV *class
34             SV *repo
35             SV *msg
36             Signature author
37             Signature committer
38             AV *parents
39             Tree tree
40              
41             PREINIT:
42             int rc;
43              
44             SV **c;
45 35           size_t i = 0, count = 0;
46             git_oid oid;
47              
48             Repository repo_ptr;
49              
50 35           const char *update_ref = "HEAD";
51              
52 35           Commit commit, *commit_parents = NULL;
53              
54             CODE:
55 35 100         if (items > 7) {
56 6           SV *sv_update_ref = ST(7);
57              
58 6 100         if (SvOK(sv_update_ref))
    50          
    50          
59 1           update_ref = git_ensure_pv(sv_update_ref, "update_ref");
60             else
61 5           update_ref = NULL;
62             }
63              
64 63 100         while ((c = av_fetch(parents, i++, 0))) {
65 28 50         if (!c || !SvOK(*c))
    50          
    0          
    0          
66 0           continue;
67              
68 28 50         Renew(commit_parents, count + 1, git_commit *);
69 28           commit_parents[count++] = GIT_SV_TO_PTR(Commit, *c);
70             }
71              
72 35           repo_ptr = GIT_SV_TO_PTR(Repository, repo);
73              
74 35           rc = git_commit_create(
75             &oid, repo_ptr -> repository, update_ref, author, committer, NULL,
76             git_ensure_pv(msg, "msg"), tree, count,
77             (const git_commit **) commit_parents
78             );
79              
80 35           Safefree(commit_parents);
81 35           git_check_error(rc);
82              
83 35           rc = git_commit_lookup(&commit, repo_ptr -> repository, &oid);
84 35           git_check_error(rc);
85              
86 35 50         GIT_NEW_OBJ_WITH_MAGIC(
87             RETVAL, SvPVbyte_nolen(class), commit, SvRV(repo)
88             );
89              
90             OUTPUT: RETVAL
91              
92             SV *
93             lookup(class, repo, id)
94             SV *class
95             SV *repo
96             SV *id
97              
98             PREINIT:
99             int rc;
100              
101             git_oid oid;
102              
103             Commit commit;
104             Repository repo_ptr;
105              
106             STRLEN len;
107             const char *id_str;
108              
109             INIT:
110 4           id_str = git_ensure_pv_with_len(id, "id", &len);
111              
112             CODE:
113 4           rc = git_oid_fromstrn(&oid, id_str, len);
114 4           git_check_error(rc);
115              
116 4           repo_ptr = GIT_SV_TO_PTR(Repository, repo);
117 4           rc = git_commit_lookup_prefix(&commit, repo_ptr -> repository, &oid, len);
118              
119 4 100         if (rc == GIT_ENOTFOUND) {
120 2           RETVAL = &PL_sv_undef;
121             } else {
122 2           git_check_error(rc);
123              
124 2 50         GIT_NEW_OBJ_WITH_MAGIC(
125             RETVAL, SvPVbyte_nolen(class), commit, SvRV(repo)
126             );
127             }
128              
129             OUTPUT: RETVAL
130              
131             SV *
132             owner(self)
133             SV *self
134              
135             PREINIT:
136             SV *repo;
137              
138             CODE:
139 2           repo = GIT_SV_TO_MAGIC(self);
140 2           RETVAL = newRV_inc(repo);
141              
142             OUTPUT: RETVAL
143              
144             SV *
145             id(self)
146             Commit self
147              
148             CODE:
149 142           RETVAL = git_oid_to_sv(git_commit_id(self));
150              
151             OUTPUT: RETVAL
152              
153             SV *
154             message(self)
155             Commit self
156              
157             PREINIT:
158             const char *msg;
159              
160             CODE:
161 24           msg = git_commit_message(self);
162 24           RETVAL = newSVpv(msg, 0);
163              
164             OUTPUT: RETVAL
165              
166             SV *
167             message_trailers(self)
168             Commit self
169              
170             PREINIT:
171             int rc;
172             size_t i;
173             const char *msg;
174 2           git_message_trailer_array trailers = {0};
175             HV *result;
176              
177             CODE:
178 2           msg = git_commit_message(self);
179 2 50         if (msg == NULL)
180 0           XSRETURN_UNDEF;
181              
182 2           rc = git_message_trailers(&trailers, msg);
183 2           git_check_error(rc);
184              
185 2           result = newHV();
186              
187 6 100         for (i = 0; i < trailers.count; ++i) {
188 4           const char *key = trailers.trailers[i].key;
189 4           const char *value = trailers.trailers[i].value;
190 4           STRLEN length = strlen (key);
191              
192 4 100         if (!hv_exists(result, key, length))
193 2           hv_store(result, key, length, newRV_noinc (MUTABLE_SV (newAV())), 0);
194              
195 4           av_push (MUTABLE_AV (SvRV (*hv_fetch(result, key, length, 0))),
196             newSVpv(value, 0));
197             }
198              
199 2           git_message_trailer_array_free(&trailers);
200 2           RETVAL = newRV_noinc (MUTABLE_SV (result));
201              
202             OUTPUT: RETVAL
203              
204             SV *
205             summary(self)
206             Commit self
207              
208             PREINIT:
209             const char *summary;
210              
211             CODE:
212 19           summary = git_commit_summary(self);
213 19           RETVAL = newSVpv(summary, 0);
214              
215             OUTPUT: RETVAL
216              
217             SV *
218             body(self)
219             Commit self
220              
221             PREINIT:
222             const char *body;
223              
224             CODE:
225 1           body = git_commit_body(self);
226 1           RETVAL = newSVpv(body, 0);
227              
228             OUTPUT: RETVAL
229              
230             Signature
231             author(self)
232             Commit self
233              
234             PREINIT:
235             int rc;
236             Signature a, r;
237              
238             CODE:
239 24           a = (Signature) git_commit_author(self);
240 24           rc = git_signature_dup(&r, a);
241 24           git_check_error(rc);
242              
243 24           RETVAL = r;
244              
245             OUTPUT: RETVAL
246              
247             Signature
248             committer(self)
249             Commit self
250              
251             PREINIT:
252             int rc;
253             Signature c, r;
254              
255             CODE:
256 21           c = (Signature) git_commit_committer(self);
257 21           rc = git_signature_dup(&r, c);
258 21           git_check_error(rc);
259              
260 21           RETVAL = r;
261              
262             OUTPUT: RETVAL
263              
264             SV *
265             time(self)
266             Commit self
267              
268             PREINIT:
269             char *buf;
270             git_time_t time;
271              
272             CODE:
273 3           time = git_commit_time(self);
274              
275 3           Newx(buf, snprintf(NULL, 0, "%" PRId64, time) + 1, char);
276 3           sprintf(buf, "%" PRId64, time);
277              
278 3           RETVAL = newSVpv(buf, 0);
279 3           Safefree(buf);
280              
281             OUTPUT: RETVAL
282              
283             int
284             offset(self)
285             Commit self
286              
287             CODE:
288 3           RETVAL = git_commit_time_offset(self);
289              
290             OUTPUT: RETVAL
291              
292             SV *
293             tree(self)
294             SV *self
295              
296             PREINIT:
297             int rc;
298              
299             SV *repo;
300             Tree tree;
301              
302             CODE:
303 33           repo = GIT_SV_TO_MAGIC(self);
304              
305 33           rc = git_commit_tree(&tree, GIT_SV_TO_PTR(Commit, self));
306 33           git_check_error(rc);
307              
308 33           GIT_NEW_OBJ_WITH_MAGIC(RETVAL, "Git::Raw::Tree", tree, repo);
309              
310             OUTPUT: RETVAL
311              
312             void
313             parents(self)
314             SV *self
315              
316             PREINIT:
317             int ctx;
318              
319             PPCODE:
320 7 50         ctx = GIMME_V;
321              
322 7 100         if (ctx != G_VOID) {
323             int rc, count;
324             Commit child;
325 6           SV *repo = GIT_SV_TO_MAGIC(self);
326              
327 6           child = GIT_SV_TO_PTR(Commit, self);
328 6           count = git_commit_parentcount(child);
329              
330 6 100         if (ctx == G_ARRAY) {
331             int i;
332              
333 8 100         for (i = 0; i < count; i++) {
334             SV *tmp;
335             Commit parent;
336              
337 4           rc = git_commit_parent(&parent, child, i);
338 4           git_check_error(rc);
339              
340 4           GIT_NEW_OBJ_WITH_MAGIC(
341             tmp, "Git::Raw::Commit", parent, repo
342             );
343 4 50         mXPUSHs(tmp);
344             }
345              
346 4           XSRETURN((int) count);
347             } else {
348 2 50         mXPUSHs(newSViv((int) count));
349 2           XSRETURN(1);
350             }
351             } else
352 1           XSRETURN_EMPTY;
353              
354             SV *
355             merge(self, commit, ...)
356             SV *self
357             Commit commit
358              
359             PROTOTYPE: $;$;$
360             PREINIT:
361             int rc;
362              
363             SV *repo;
364             Repository repo_ptr;
365              
366             Index index;
367 1           git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
368              
369             CODE:
370 1           repo = GIT_SV_TO_MAGIC(self);
371 1 50         repo_ptr = INT2PTR(Repository, SvIV((SV *) repo));
372              
373 1 50         if (items == 3) {
374 1           HV *opts = git_ensure_hv(ST(2), "merge_opts");
375 1           git_hv_to_merge_opts(opts, &merge_opts);
376             }
377              
378 1           rc = git_merge_commits(
379             &index,
380             repo_ptr -> repository,
381 1           GIT_SV_TO_PTR(Commit, self),
382             commit, &merge_opts);
383 1           git_check_error(rc);
384              
385 1           GIT_NEW_OBJ_WITH_MAGIC(
386             RETVAL, "Git::Raw::Index", index, repo
387             );
388              
389             OUTPUT: RETVAL
390              
391             SV *
392             ancestor(self, gen)
393             SV *self
394             unsigned int gen
395              
396             PREINIT:
397             int rc;
398              
399             SV *repo;
400             Commit anc;
401              
402             CODE:
403 6           repo = GIT_SV_TO_MAGIC(self);
404              
405 6           rc = git_commit_nth_gen_ancestor(
406             &anc,
407 6           GIT_SV_TO_PTR(Commit, self),
408             gen
409             );
410 6           git_check_error(rc);
411              
412 5           GIT_NEW_OBJ_WITH_MAGIC(
413             RETVAL, "Git::Raw::Commit", anc, repo
414             );
415              
416             OUTPUT: RETVAL
417              
418             SV *
419             as_email(commit, ...)
420             Commit commit
421              
422             PROTOTYPE: $;$$
423             PREINIT:
424             int rc;
425              
426             git_repository *repo;
427 3           git_buf buf = GIT_BUF_INIT_CONST(NULL, 0);
428 3           git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
429 3           git_diff_format_email_flags_t flags = GIT_DIFF_FORMAT_EMAIL_NONE;
430              
431 3           size_t patch_no = 1, total_patches = 1;
432              
433             CODE:
434 3 100         if (items >= 2) {
435 2 50         if (SvOK(ST(1))) {
    0          
    0          
436             SV *opt;
437             HV *hopt;
438             HV *opts;
439              
440 2           opts = git_ensure_hv(ST(1), "format_opts");
441              
442 2 50         if ((opt = git_hv_int_entry(opts, "patch_no")))
443 2 50         patch_no = (size_t) SvIV(opt);
444              
445 2 50         if ((opt = git_hv_int_entry(opts, "total_patches")))
446 2 50         total_patches = (size_t) SvIV(opt);
447              
448 2 100         if ((hopt = git_hv_hash_entry(opts, "flags"))) {
449 1 50         if ((opt = git_hv_int_entry(hopt, "exclude_subject_patch_marker"))) {
450 1 50         if (SvIV(opt))
    50          
451 1           flags |= GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER;
452             }
453             }
454             }
455             }
456              
457 3 100         if (items >= 3) {
458 1           HV *opts = git_ensure_hv(ST(2), "diff_opts");
459 1           git_hv_to_diff_opts(opts, &diff_opts, NULL);
460             }
461              
462 3           repo = git_commit_owner(commit);
463              
464 3           rc = git_diff_commit_as_email(
465             &buf, repo, commit,
466             patch_no, total_patches,
467             flags,
468             &diff_opts
469             );
470 3 50         if (rc != GIT_OK) {
471 0           git_buf_dispose(&buf);
472 0           git_check_error(rc);
473             }
474              
475 3           RETVAL = newSVpv(buf.ptr, buf.size);
476 3           git_buf_dispose(&buf);
477              
478             OUTPUT: RETVAL
479              
480             SV *
481             diff(self, ...)
482             SV *self
483              
484             PROTOTYPE: $;$$
485             PREINIT:
486             int rc;
487 7           unsigned int parent_count, requested_parent = 0;
488              
489             SV *repo;
490             Repository repo_ptr;
491              
492             Diff diff;
493 7           Commit commit, parent = NULL;
494 7           Tree our_tree = NULL, parent_tree = NULL;
495              
496 7           git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
497              
498             CODE:
499 7           commit = GIT_SV_TO_PTR(Commit, self);
500              
501 7           parent_count = git_commit_parentcount(commit);
502 7 100         if (items >= 2) {
503 5 100         if (SvOK(ST(1))) {
    50          
    50          
504 4 100         if (parent_count == 0)
505 2           croak_usage("Commit has no parents");
506              
507 2           requested_parent = git_ensure_iv(ST(1), "parent");
508             }
509             }
510              
511 5 100         if (items >= 3) {
512 1           HV *opts = git_ensure_hv(ST(2), "diff_opts");
513 1           git_hv_to_diff_opts(opts, &diff_opts, NULL);
514             }
515              
516 5 100         if (parent_count > 0) {
517 3 100         if (requested_parent > (parent_count - 1))
518 1           croak_usage("Commit parent %u is out of range", requested_parent);
519              
520 2           rc = git_commit_parent(&parent, commit, 0);
521 2           git_check_error(rc);
522              
523 2           rc = git_commit_tree(&parent_tree, parent);
524 2           git_check_error(rc);
525             }
526              
527 4           rc = git_commit_tree(&our_tree, commit);
528 4           git_check_error(rc);
529              
530 4           repo = GIT_SV_TO_MAGIC(self);
531 4 50         repo_ptr = INT2PTR(Repository, SvIV((SV *) repo));
532              
533 4           rc = git_diff_tree_to_tree(
534             &diff, repo_ptr -> repository,
535             parent_tree, our_tree, &diff_opts
536             );
537 4           git_check_error(rc);
538              
539 4           GIT_NEW_OBJ_WITH_MAGIC(
540             RETVAL, "Git::Raw::Diff", diff, repo
541             );
542              
543             OUTPUT: RETVAL
544              
545             void
546             DESTROY(self)
547             SV *self
548              
549             CODE:
550 212           git_commit_free(GIT_SV_TO_PTR(Commit, self));
551 212           SvREFCNT_dec(GIT_SV_TO_MAGIC(self));