File Coverage

Raw.xs
Criterion Covered Total %
statement 872 1193 73.0
branch 535 1748 30.6
condition n/a
subroutine n/a
pod n/a
total 1407 2941 47.8


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #define NEED_newRV_noinc
6             #define NEED_sv_2pvbyte
7             #define NEED_sv_2pv_flags
8              
9             #include "ppport.h"
10              
11             #ifndef MUTABLE_AV
12             #define MUTABLE_AV(p) ((AV *)MUTABLE_PTR(p))
13             #endif
14              
15             #ifdef GIT_SSH
16             #include
17             #else
18             #include "libssh2-compat.h"
19             #endif
20              
21             #include
22             #include
23             #include
24             #include
25              
26             /* internally generated errors */
27             #define ASSERT -10000
28             #define USAGE -10001
29             #define RESOLVE -10002
30              
31             /* internally generated classes */
32             #define INTERNAL -20000
33              
34             #include "constants-error-code.h"
35             #include "constants-error-category.h"
36             #include "constants-object.h"
37             #include "constants-packbuilder.h"
38             #include "constants-rebase-operation.h"
39             #include "constants-stash-progress.h"
40              
41             #ifdef _MSC_VER
42             #pragma warning (disable : 4244 4267 )
43             #endif
44              
45             typedef struct {
46             SV *initialize;
47             SV *shutdown;
48             SV *check;
49             SV *apply;
50             SV *cleanup;
51             } git_filter_callbacks;
52              
53             typedef git_annotated_commit * AnnotatedCommit;
54             typedef git_blame * Blame;
55             typedef git_blame_hunk * Blame_Hunk;
56             typedef git_blob * Blob;
57             typedef git_reference * Branch;
58             typedef git_cert * Cert;
59             typedef git_cert_hostkey * Cert_HostKey;
60             typedef git_cert_x509 * Cert_X509;
61             typedef git_commit * Commit;
62             typedef git_config * Config;
63             typedef git_diff * Diff;
64             typedef git_diff_delta * Diff_Delta;
65             typedef git_diff_file * Diff_File;
66             typedef git_diff_hunk * Diff_Hunk;
67             typedef git_diff_stats * Diff_Stats;
68             typedef git_index * Index;
69             typedef git_index_entry * Index_Entry;
70             typedef git_indexer * Indexer;
71             typedef git_odb_backend * Mempack;
72             typedef git_merge_file_result * Merge_File_Result;
73             typedef git_note * Note;
74             typedef git_object * Object;
75              
76             typedef struct {
77             git_odb *odb;
78             AV *backends;
79             } git_raw_odb;
80              
81             typedef git_raw_odb * Odb;
82             typedef git_odb_backend * Odb_Backend;
83             typedef git_odb_object * Odb_Object;
84              
85             typedef struct {
86             git_packbuilder *packbuilder;
87             HV *callbacks;
88             } git_raw_packbuilder;
89              
90             typedef git_raw_packbuilder *Packbuilder;
91             typedef git_patch * Patch;
92             typedef git_pathspec * PathSpec;
93             typedef git_pathspec_match_list * PathSpec_MatchList;
94             typedef git_rebase * Rebase;
95             typedef git_rebase_operation * Rebase_Operation;
96             typedef git_reference * Reference;
97             typedef git_reflog * Reflog;
98             typedef git_reflog_entry * Reflog_Entry;
99              
100             typedef struct {
101             git_refspec *refspec;
102             int owned;
103             } git_raw_refspec;
104              
105             typedef git_raw_refspec * RefSpec;
106              
107             typedef git_signature * Signature;
108             typedef git_tag * Tag;
109             typedef git_transfer_progress * TransferProgress;
110             typedef git_tree * Tree;
111             typedef git_treebuilder * Tree_Builder;
112             typedef git_tree_entry * Tree_Entry;
113             typedef git_revwalk * Walker;
114             typedef git_worktree * Worktree;
115              
116             typedef struct {
117             git_index_entry *ours;
118             git_index_entry *ancestor;
119             git_index_entry *theirs;
120             } git_raw_index_conflict;
121              
122             typedef git_raw_index_conflict * Index_Conflict;
123              
124             typedef struct {
125             int code;
126             int category;
127             SV *message;
128             const char *file;
129             unsigned int line;
130             } git_raw_error;
131              
132             typedef git_raw_error * Error;
133              
134             typedef struct {
135             git_filter filter;
136             git_filter_callbacks callbacks;
137             char *name;
138             char *attributes;
139             } git_raw_filter;
140              
141             typedef git_raw_filter * Filter;
142             typedef git_filter_source * Filter_Source;
143             typedef git_filter_list * Filter_List;
144              
145             typedef struct {
146             git_remote *remote;
147             int owned;
148             } git_raw_remote;
149              
150             typedef git_raw_remote * Remote;
151              
152             typedef struct {
153             git_repository *repository;
154             int owned;
155             } git_raw_repository;
156              
157             typedef git_raw_repository * Repository;
158              
159             typedef git_submodule * Submodule;
160              
161             typedef struct {
162             git_cred *cred;
163             SV *callback;
164             int fail_count;
165             } git_raw_cred;
166              
167             typedef git_raw_cred * Cred;
168              
169             /* printf format specifier for size_t */
170             #if defined(_MSC_VER) || defined(__MINGW32__)
171             # define PRIuZ "Iu"
172             # define PRIxZ "Ix"
173             #else
174             # define PRIuZ "zu"
175             # define PRIxZ "zx"
176             #endif
177              
178             STATIC MGVTBL null_mg_vtbl = {
179             NULL, /* get */
180             NULL, /* set */
181             NULL, /* len */
182             NULL, /* clear */
183             NULL, /* free */
184             #if MGf_COPY
185             NULL, /* copy */
186             #endif /* MGf_COPY */
187             #if MGf_DUP
188             NULL, /* dup */
189             #endif /* MGf_DUP */
190             #if MGf_LOCAL
191             NULL, /* local */
192             #endif /* MGf_LOCAL */
193             };
194              
195 700           STATIC void xs_object_magic_attach_struct(pTHX_ SV *sv, void *ptr) {
196 700           sv_magicext(sv, NULL, PERL_MAGIC_ext, &null_mg_vtbl, ptr, 0);
197 700           }
198              
199 1137           STATIC void *xs_object_magic_get_struct(pTHX_ SV *sv) {
200 1137           MAGIC *mg = NULL;
201              
202 1137 50         if (SvTYPE(sv) >= SVt_PVMG) {
203             MAGIC *tmp;
204              
205 2263 100         for (tmp = SvMAGIC(sv); tmp;
206 1126           tmp = tmp -> mg_moremagic) {
207 1126 50         if ((tmp -> mg_type == PERL_MAGIC_ext) &&
    50          
208 1126           (tmp -> mg_virtual == &null_mg_vtbl))
209 1126           mg = tmp;
210             }
211             }
212              
213 1137 100         return (mg) ? mg -> mg_ptr : NULL;
214             }
215              
216             #define GIT_SV_TO_MAGIC(SV) \
217             xs_object_magic_get_struct(aTHX_ SvRV(SV))
218              
219             #define GIT_NEW_OBJ(rv, class, sv) \
220             STMT_START { \
221             (rv) = sv_setref_pv(newSV(0), class, sv); \
222             } STMT_END
223              
224             #define GIT_NEW_OBJ_WITH_MAGIC(rv, class, sv, magic) \
225             STMT_START { \
226             (rv) = sv_setref_pv(newSV(0), class, sv); \
227             \
228             xs_object_magic_attach_struct( \
229             aTHX_ SvRV(rv), SvREFCNT_inc_NN(magic) \
230             ); \
231             } STMT_END
232              
233             #define GIT_OBJ_SET_MAGIC(sv, magic) \
234             STMT_START { \
235             xs_object_magic_attach_struct( \
236             aTHX_ SvRV(sv), SvREFCNT_inc_NN(magic) \
237             ); \
238             } STMT_END
239              
240 92           STATIC const COP* git_closest_cop(pTHX_ const COP *cop, const OP *o, const OP *curop, bool opnext) {
241             dVAR;
242              
243 92 50         if (!o || !curop || (
    50          
    50          
    0          
    100          
244 0 0         opnext ? o->op_next == curop && o->op_type != OP_SCOPE : o == curop
    0          
245             ))
246 89           return cop;
247              
248 3 100         if (o->op_flags & OPf_KIDS) {
249             const OP *kid;
250 3 50         for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) {
    50          
251             const COP *new_cop;
252              
253 3 50         if (kid->op_type == OP_NULL && kid->op_targ == OP_NEXTSTATE)
    0          
254 0           cop = (const COP *)kid;
255              
256             /* Keep searching, and return when we've found something. */
257 3           new_cop = git_closest_cop(aTHX_ cop, kid, curop, opnext);
258 3 100         if (new_cop)
259 2           return new_cop;
260             }
261             }
262              
263 1           return NULL;
264             }
265              
266 89           STATIC Error create_error_obj(int code, int category, SV *message) {
267             Error e;
268             const COP *cop;
269              
270 89           Newxz(e, 1, git_raw_error);
271 89           e -> code = code;
272 89           e -> category = category;
273 89           e -> message = message;
274              
275 89 50         cop = git_closest_cop(aTHX_ PL_curcop, OpSIBLING(PL_curcop), PL_op, FALSE);
276 89 50         if (cop == NULL)
277 0           cop = PL_curcop;
278              
279 89 50         if (CopLINE (cop)) {
280 89 50         e -> file = CopFILE (cop);
281 89           e -> line = CopLINE (cop);
282             } else
283 0           e -> file = "unknown";
284              
285 89           return e;
286             }
287              
288 67           STATIC Error create_error_obj_fmt(int code, int category, const char *prefix, const char *pat, va_list *list) {
289             Error e;
290              
291 67           e = create_error_obj(code, category, newSVpv(prefix, 0));
292 67           sv_vcatpvf(e -> message, pat, list);
293              
294 67           return e;
295             }
296              
297 89           STATIC void __attribute__noreturn__ croak_error_obj(Error e) {
298 89           SV *res = NULL;
299 89           GIT_NEW_OBJ(res, "Git::Raw::Error", e);
300 89           SvREFCNT_inc(e -> message);
301 89           croak_sv(res);
302             }
303              
304 1763           STATIC void S_git_check_error(int err, const char *file, int line) {
305 1763 100         if (err != GIT_OK && err != GIT_ITEROVER) {
    100          
306             const git_error *error;
307             Error e;
308              
309 22           e = create_error_obj(err, GITERR_NONE, NULL);
310              
311 22 100         if ((error = giterr_last()) != NULL) {
312 20           e -> category = error -> klass;
313 20           e -> message = newSVpv(error -> message, 0);
314 2 50         } else if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
315 1 50         e -> message = newSVpv(SvPVbyte_nolen(ERRSV), 0);
    50          
    50          
    0          
316             } else {
317 1           e -> message = newSVpvf("Unknown error! (%s:%d)", file, line);
318             }
319              
320 22           croak_error_obj(e);
321             }
322 1741           }
323              
324             #define git_check_error(e) S_git_check_error(e, __FILE__, __LINE__)
325              
326 1           STATIC void S_croak_assert(const char *pat, const char *file, int line, ...) {
327             Error e;
328             va_list list;
329              
330 1           va_start(list, line);
331 1           e = create_error_obj_fmt(ASSERT, INTERNAL,
332 1           form("Assertion failed @ (%s:%d). Please file a bug report.\n\n", file, line),
333             pat, &list
334             );
335 1           va_end(list);
336              
337 1           croak_error_obj(e);
338             }
339              
340             #define croak_assert(pat, ...) S_croak_assert (pat, __FILE__, __LINE__, __VA_ARGS__)
341              
342 53           STATIC void croak_usage(const char *pat, ...) {
343             Error e;
344             va_list list;
345              
346 53           va_start(list, pat);
347 53           e = create_error_obj_fmt(USAGE, INTERNAL, "", pat, &list);
348 53           va_end(list);
349              
350 53           croak_error_obj(e);
351             }
352              
353 13           STATIC void croak_resolve(const char *pat, ...) {
354             Error e;
355             va_list list;
356              
357 13           va_start(list, pat);
358 13           e = create_error_obj_fmt(RESOLVE, INTERNAL, "", pat, &list);
359 13           va_end(list);
360              
361 13           croak_error_obj(e);
362             }
363              
364 25           STATIC git_index_entry *git_index_entry_dup(const git_index_entry *entry,
365             const char *new_path)
366             {
367 25           git_index_entry *new_entry = NULL;
368              
369 25 50         if (entry) {
370 25           Newxz(new_entry, 1, git_index_entry);
371 25           StructCopy(entry, new_entry, git_index_entry);
372              
373 25 100         if (new_path)
374 1           new_entry -> path = savepv(new_path);
375             else
376 24           new_entry -> path = savepv(entry -> path);
377             }
378              
379 25           return new_entry;
380             }
381              
382 25           STATIC void git_index_entry_free(git_index_entry *entry)
383             {
384 25 50         if (entry) {
385 25           Safefree(entry -> path);
386 25           Safefree(entry);
387             }
388 25           }
389              
390 19           STATIC SV *git_index_entry_to_sv(const git_index_entry *index_entry, const char *path, SV *repo) {
391 19           SV *ie = &PL_sv_undef;
392              
393 19 50         if (index_entry) {
394 19           git_index_entry *entry = NULL;
395              
396 19 50         if ((entry = git_index_entry_dup(index_entry, path))) {
397 19           GIT_NEW_OBJ_WITH_MAGIC(
398             ie, "Git::Raw::Index::Entry",
399             entry, repo
400             );
401             }
402             }
403              
404 19           return ie;
405             }
406              
407 140           STATIC SV *git_obj_to_sv(git_object *o, SV *repo) {
408 140           SV *res = NULL;
409              
410 140           switch (git_object_type(o)) {
411             case GIT_OBJ_BLOB:
412 28           GIT_NEW_OBJ_WITH_MAGIC(
413             res, "Git::Raw::Blob", o, repo
414             );
415 28           break;
416              
417             case GIT_OBJ_COMMIT:
418 102           GIT_NEW_OBJ_WITH_MAGIC(
419             res, "Git::Raw::Commit", o, repo
420             );
421 102           break;
422              
423             case GIT_OBJ_TAG:
424 0           GIT_NEW_OBJ_WITH_MAGIC(
425             res, "Git::Raw::Tag", o, repo
426             );
427 0           break;
428              
429             case GIT_OBJ_TREE:
430 10           GIT_NEW_OBJ_WITH_MAGIC(
431             res, "Git::Raw::Tree", o, repo
432             );
433 10           break;
434              
435             default:
436 0           croak_usage("Invalid object type");
437 0           break;
438             }
439              
440 140           return res;
441             }
442              
443 44           STATIC git_object *git_sv_to_obj(SV *sv) {
444 88           if (sv_isobject(sv) && (
445 88 100         sv_derived_from(sv, "Git::Raw::Blob") ||
446 66 50         sv_derived_from(sv, "Git::Raw::Commit") ||
447 44 100         sv_derived_from(sv, "Git::Raw::Tag") ||
448 22           sv_derived_from(sv, "Git::Raw::Tree")
449             ))
450 27 50         return INT2PTR(git_object *, SvIV((SV *) SvRV(sv)));
451              
452 17           return NULL;
453             }
454              
455 1772           STATIC void *git_sv_to_ptr(const char *type, SV *sv, const char *file, int line) {
456 1772           SV *full_type = sv_2mortal(newSVpvf("Git::Raw::%s", type));
457              
458 1772 50         if (sv_isobject(sv) && sv_derived_from(sv, SvPV_nolen(full_type)))
    50          
    100          
459 1767 50         return INT2PTR(void *, SvIV((SV *) SvRV(sv)));
460              
461 5 50         croak_usage("Argument is not of type %s @ (%s:%d)",
462 5           SvPV_nolen(full_type), file, line);
463              
464 0           return NULL;
465             }
466              
467             #define GIT_SV_TO_PTR(type, sv) \
468             git_sv_to_ptr(#type, sv, __FILE__, __LINE__)
469              
470 1           STATIC void git_sv_set_ptr(const char *type, SV *sv, void *ptr, const char *file, int line) {
471 1           SV *full_type = sv_2mortal(newSVpvf("Git::Raw::%s", type));
472              
473 1 50         if (!(sv_isobject(sv) && sv_derived_from(sv, SvPV_nolen(full_type))))
    50          
    50          
474 0 0         croak_assert("Argument is not of type %s @ (%s:%d)",
475             SvPV_nolen(full_type), file, line);
476              
477 1           sv_setiv(SvRV(sv), PTR2IV(ptr));
478 1           }
479              
480             #define GIT_SV_SET_PTR(type, sv, ptr) \
481             git_sv_set_ptr(#type, sv, ptr, __FILE__, __LINE__)
482              
483 405           STATIC SV *git_oid_to_sv(const git_oid *oid) {
484             char out[41];
485              
486 405           git_oid_fmt(out, oid);
487 405           out[40] = '\0';
488              
489 405           return newSVpv(out, 0);
490             }
491              
492 110           STATIC git_oid *git_sv_to_commitish(git_repository *repo, SV *sv, git_oid *oid) {
493 110           git_oid *result = NULL;
494 110           git_reference *ref = NULL;
495 110           git_object *obj = NULL;
496              
497 110 100         if (sv_isobject(sv)) {
498 68 100         if (sv_derived_from(sv, "Git::Raw::Reference")) {
499 10           int rc = git_reference_peel(&obj,
500 10           GIT_SV_TO_PTR(Reference, sv),
501             GIT_OBJ_COMMIT
502             );
503 10           git_check_error(rc);
504              
505 10           git_oid_cpy(oid, git_object_id(obj));
506 58 50         } else if (sv_derived_from(sv, "Git::Raw::Commit")) {
507 58           git_oid_cpy(oid, git_commit_id(GIT_SV_TO_PTR(Commit, sv)));
508             } else
509 0           goto on_error;
510             } else {
511             STRLEN len;
512 42           const char *commitish_name = NULL;
513              
514             /* substr() may return a SVt_PVLV, need to perform some force majeur */
515 42 100         if (SvPOK(sv) || SvGAMAGIC(sv)) {
    50          
    50          
    50          
    0          
516 41 100         commitish_name = SvPVbyte(sv, len);
517 1 50         } else if (SvTYPE(sv) == SVt_PVLV) {
518 0 0         commitish_name = SvPVbyte_force(sv, len);
519             }
520              
521 42 100         if (commitish_name) {
522             /* first try and see if its a commit id, or if its a reference */
523 41 100         if (git_oid_fromstrn(oid, commitish_name, len) >= 0) {
524 23 100         if (len < GIT_OID_MINPREFIXLEN)
525 13           goto on_error;
526              
527 22 100         if (len != GIT_OID_HEXSZ) {
528 7 100         if (git_object_lookup_prefix(&obj, repo, oid,
529             len, GIT_OBJ_COMMIT) < 0)
530 2           goto on_error;
531              
532 20           git_oid_cpy(oid, git_object_id(obj));
533             }
534             } else {
535 28           if (git_reference_lookup(&ref, repo, commitish_name) < 0 &&
536 10           git_reference_dwim(&ref, repo, commitish_name) < 0)
537 9           goto on_error;
538              
539 9 50         if (git_reference_peel(&obj, ref, GIT_OBJ_COMMIT) < 0)
540 0           goto on_error;
541              
542 29           git_oid_cpy(oid, git_object_id(obj));
543             }
544             } else
545 1           goto on_error;
546             }
547              
548 97           result = oid;
549              
550             on_error:
551 110           git_object_free(obj);
552 110           git_reference_free(ref);
553 110           return result;
554             }
555              
556 9           STATIC void git_clean_filter_callbacks(git_filter_callbacks *cbs) {
557 9 100         if (cbs -> initialize) {
558 1           SvREFCNT_dec(cbs -> initialize);
559 1           cbs -> initialize = NULL;
560             }
561              
562 9 100         if (cbs -> shutdown) {
563 2           SvREFCNT_dec(cbs -> shutdown);
564 2           cbs -> shutdown = NULL;
565             }
566              
567 9 100         if (cbs -> check) {
568 3           SvREFCNT_dec(cbs -> check);
569 3           cbs -> check = NULL;
570             }
571              
572 9 100         if (cbs -> apply) {
573 5           SvREFCNT_dec(cbs -> apply);
574 5           cbs -> apply = NULL;
575             }
576              
577 9 100         if (cbs -> cleanup) {
578 1           SvREFCNT_dec(cbs -> cleanup);
579 1           cbs -> cleanup = NULL;
580             }
581 9           }
582              
583 12           STATIC SV *git_hv_sv_entry(HV *hv, const char *name) {
584             SV **opt;
585              
586 12 50         if ((opt = hv_fetch(hv, name, strlen(name), 0)))
587 12           return *opt;
588              
589 0           return NULL;
590             }
591              
592 1027           STATIC SV *git_hv_int_entry(HV *hv, const char *name) {
593             SV **opt;
594              
595 1027 100         if ((opt = hv_fetch(hv, name, strlen(name), 0))) {
596 112 50         if (!SvIOK(*opt))
597 0           croak_usage("Expected an integer for '%s'", name);
598              
599 112           return *opt;
600             }
601              
602 915           return NULL;
603             }
604              
605 221           STATIC SV *git_hv_string_entry(HV *hv, const char *name) {
606             SV **opt;
607              
608 221 100         if ((opt = hv_fetch(hv, name, strlen(name), 0))) {
609 23 50         if (!SvPOK(*opt))
610 0           croak_usage("Expected a string for '%s'", name);
611              
612 23           return *opt;
613             }
614              
615 198           return NULL;
616             }
617              
618 30           STATIC AV *git_ensure_av(SV *sv, const char *identifier) {
619 30 50         if (!SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVAV)
    50          
620 0           croak_usage("Invalid type for '%s', expected a list", identifier);
621              
622 30           return (AV *) SvRV(sv);
623             }
624              
625 140           STATIC HV *git_ensure_hv(SV *sv, const char *identifier) {
626 140 100         if (!SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVHV)
    100          
627 3           croak_usage("Invalid type for '%s', expected a hash", identifier);
628              
629 137           return (HV *) SvRV(sv);
630             }
631              
632 53           STATIC SV *git_ensure_cv(SV *sv, const char *identifier) {
633 53 50         if (!SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVCV)
    50          
634 0           croak_usage("Invalid type for '%s', expected a code reference", identifier);
635              
636 53           return sv;
637             }
638              
639 32           STATIC I32 git_ensure_iv(SV *sv, const char *identifier) {
640 32 100         if (!SvIOK(sv))
641 2           croak_usage("Invalid type for '%s', expected an integer", identifier);
642              
643 30 50         return SvIV(sv);
644             }
645              
646 465           STATIC const char *git_ensure_pv_with_len(SV *sv, const char *identifier, STRLEN *len) {
647 465           const char *pv = NULL;
648             STRLEN real_len;
649              
650 465 100         if (SvPOK(sv) || SvGAMAGIC(sv)) {
    50          
    0          
    0          
    0          
651 465 100         pv = SvPVbyte(sv, real_len);
652 0 0         } else if (SvTYPE(sv) == SVt_PVLV) {
653 0 0         pv = SvPVbyte_force(sv, real_len);
654             }
655              
656 465 50         if (pv == NULL)
657 0           croak_usage("Invalid type for '%s', expected a string", identifier);
658              
659 465 100         if (len)
660 166           *len = real_len;
661              
662 465           return pv;
663             }
664              
665 299           STATIC const char *git_ensure_pv(SV *sv, const char *identifier) {
666 299           return git_ensure_pv_with_len(sv, identifier, NULL);
667             }
668              
669 75           STATIC SV *git_hv_code_entry(HV *hv, const char *name) {
670             SV **opt;
671              
672 75 100         if ((opt = hv_fetch(hv, name, strlen(name), 0)))
673 43           return git_ensure_cv(*opt, name);
674              
675 32           return NULL;
676             }
677              
678 217           STATIC HV *git_hv_hash_entry(HV *hv, const char *name) {
679             SV **opt;
680              
681 217 100         if ((opt = hv_fetch(hv, name, strlen(name), 0)))
682 84           return git_ensure_hv(*opt, name);
683              
684 133           return NULL;
685             }
686              
687 60           STATIC AV *git_hv_list_entry(HV *hv, const char *name) {
688             SV **opt;
689              
690 60 100         if ((opt = hv_fetch(hv, name, strlen(name), 0)))
691 18           return git_ensure_av(*opt, name);
692              
693 42           return NULL;
694             }
695              
696 959           STATIC void git_flag_opt(HV *value, const char *name, int mask, unsigned *out) {
697             SV *opt;
698              
699 959 100         if ((opt = git_hv_int_entry(value, name)) && SvIV(opt))
    50          
    50          
700 92           *out |= mask;
701 959           }
702              
703 60           STATIC SV *get_callback_option(HV *callbacks, const char *name) {
704 60           SV *cb = NULL;
705              
706 60 100         if ((cb = git_hv_code_entry(callbacks, name)))
707 28           SvREFCNT_inc(cb);
708              
709 60           return cb;
710             }
711              
712 5           STATIC unsigned git_hv_to_diff_flag(HV *flags) {
713 5           unsigned out = 0;
714              
715 5           git_flag_opt(flags, "reverse", GIT_DIFF_REVERSE, &out);
716              
717 5           git_flag_opt(flags, "include_ignored", GIT_DIFF_INCLUDE_IGNORED, &out);
718              
719 5           git_flag_opt(flags, "include_typechange", GIT_DIFF_INCLUDE_TYPECHANGE, &out);
720              
721 5           git_flag_opt(
722             flags, "include_typechange_trees",
723             GIT_DIFF_INCLUDE_TYPECHANGE_TREES, &out);
724              
725 5           git_flag_opt(
726             flags, "recurse_ignored_dirs",
727             GIT_DIFF_RECURSE_IGNORED_DIRS, &out
728             );
729              
730 5           git_flag_opt(
731             flags, "include_untracked",
732             GIT_DIFF_INCLUDE_UNTRACKED, &out
733             );
734              
735 5           git_flag_opt(
736             flags, "recurse_untracked_dirs",
737             GIT_DIFF_RECURSE_UNTRACKED_DIRS, &out
738             );
739              
740 5           git_flag_opt(flags, "ignore_filemode", GIT_DIFF_IGNORE_FILEMODE, &out);
741              
742 5           git_flag_opt(flags, "ignore_case", GIT_DIFF_IGNORE_CASE, &out);
743              
744 5           git_flag_opt(
745             flags, "ignore_submodules",
746             GIT_DIFF_IGNORE_SUBMODULES, &out
747             );
748              
749 5           git_flag_opt(
750             flags, "ignore_whitespace",
751             GIT_DIFF_IGNORE_WHITESPACE, &out
752             );
753              
754 5           git_flag_opt(
755             flags, "ignore_whitespace_change",
756             GIT_DIFF_IGNORE_WHITESPACE_CHANGE, &out
757             );
758              
759 5           git_flag_opt(
760             flags, "ignore_whitespace_eol",
761             GIT_DIFF_IGNORE_WHITESPACE_EOL, &out
762             );
763              
764 5           git_flag_opt(
765             flags, "skip_binary_check",
766             GIT_DIFF_SKIP_BINARY_CHECK, &out
767             );
768              
769 5           git_flag_opt(
770             flags, "enable_fast_untracked_dirs",
771             GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS, &out
772             );
773              
774 5           git_flag_opt(
775             flags, "show_untracked_content",
776             GIT_DIFF_SHOW_UNTRACKED_CONTENT, &out
777             );
778              
779 5           git_flag_opt(
780             flags, "show_unmodified",
781             GIT_DIFF_SHOW_UNMODIFIED, &out
782             );
783              
784 5           git_flag_opt(flags, "patience", GIT_DIFF_PATIENCE, &out);
785              
786 5           git_flag_opt(flags, "minimal", GIT_DIFF_MINIMAL, &out);
787              
788 5           git_flag_opt(flags, "show_binary", GIT_DIFF_SHOW_BINARY, &out);
789              
790 5           git_flag_opt(flags, "force_text", GIT_DIFF_FORCE_TEXT, &out);
791              
792 5           git_flag_opt(flags, "force_binary", GIT_DIFF_FORCE_BINARY, &out);
793              
794 5           return out;
795             }
796              
797 1           STATIC unsigned git_hv_to_diff_find_flag(HV *flags) {
798 1           unsigned out = 0;
799              
800 1           git_flag_opt(flags, "renames", GIT_DIFF_FIND_RENAMES, &out);
801              
802 1           git_flag_opt(
803             flags,
804             "renames_from_rewrites",
805             GIT_DIFF_FIND_RENAMES_FROM_REWRITES, &out
806             );
807              
808 1           git_flag_opt(flags, "copies", GIT_DIFF_FIND_COPIES, &out);
809              
810 1           git_flag_opt(
811             flags,
812             "copies_from_unmodified",
813             GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED, &out
814             );
815              
816 1           git_flag_opt(flags, "rewrites", GIT_DIFF_FIND_REWRITES, &out);
817              
818 1           git_flag_opt(flags, "break_rewrites", GIT_DIFF_BREAK_REWRITES, &out);
819              
820 1           git_flag_opt(flags, "untracked", GIT_DIFF_FIND_FOR_UNTRACKED, &out);
821              
822 1           git_flag_opt(flags, "all", GIT_DIFF_FIND_ALL, &out);
823              
824 1           git_flag_opt(
825             flags,
826             "ignore_leading_whitespace",
827             GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE, &out
828             );
829              
830 1           git_flag_opt(
831             flags,
832             "ignore_whitespace",
833             GIT_DIFF_FIND_IGNORE_WHITESPACE, &out
834             );
835              
836 1           git_flag_opt(
837             flags,
838             "dont_ignore_whitespace", GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE, &out
839             );
840              
841 1           git_flag_opt(
842             flags,
843             "exact_match_only", GIT_DIFF_FIND_EXACT_MATCH_ONLY, &out
844             );
845              
846 1           git_flag_opt(
847             flags,
848             "break_rewrites_for_renames_only", GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY,
849             &out
850             );
851              
852 1           git_flag_opt(flags,
853             "remove_unmodified", GIT_DIFF_FIND_REMOVE_UNMODIFIED,
854             &out
855             );
856              
857 1           return out;
858             }
859              
860 15           STATIC unsigned git_hv_to_status_flag(HV *flags) {
861 15           unsigned out = 0;
862              
863 15           git_flag_opt(flags, "include_untracked", GIT_STATUS_OPT_INCLUDE_UNTRACKED, &out);
864 15           git_flag_opt(flags, "include_ignored", GIT_STATUS_OPT_INCLUDE_IGNORED, &out);
865 15           git_flag_opt(flags, "include_unmodified", GIT_STATUS_OPT_INCLUDE_UNMODIFIED, &out);
866 15           git_flag_opt(flags, "exclude_submodules", GIT_STATUS_OPT_EXCLUDE_SUBMODULES, &out);
867 15           git_flag_opt(flags, "recurse_untracked_dirs", GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS, &out);
868 15           git_flag_opt(flags, "disable_pathspec_match", GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH, &out);
869 15           git_flag_opt(flags, "recurse_ignored_dirs", GIT_STATUS_OPT_RECURSE_IGNORED_DIRS, &out);
870 15           git_flag_opt(flags, "renames_head_to_index", GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX, &out);
871 15           git_flag_opt(flags, "renames_index_to_workdir", GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR, &out);
872 15           git_flag_opt(flags, "sort_case_sensitively", GIT_STATUS_OPT_SORT_CASE_SENSITIVELY, &out);
873 15           git_flag_opt(flags, "sort_case_insensitively", GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY, &out);
874 15           git_flag_opt(flags, "renames_from_rewrites", GIT_STATUS_OPT_RENAMES_FROM_REWRITES, &out);
875 15           git_flag_opt(flags, "no_refresh", GIT_STATUS_OPT_NO_REFRESH, &out);
876 15           git_flag_opt(flags, "update_index", GIT_STATUS_OPT_UPDATE_INDEX, &out);
877 15           git_flag_opt(flags, "include_unreadable", GIT_STATUS_OPT_INCLUDE_UNREADABLE, &out);
878 15           git_flag_opt(flags, "include_unreadable_as_untracked", GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED, &out);
879              
880 15           return out;
881             }
882              
883 25           STATIC unsigned git_hv_to_checkout_strategy(HV *strategy) {
884 25           unsigned out = 0;
885              
886 25           git_flag_opt(strategy, "none", GIT_CHECKOUT_NONE, &out);
887              
888 25           git_flag_opt(strategy, "force", GIT_CHECKOUT_FORCE, &out);
889              
890 25           git_flag_opt(strategy, "safe", GIT_CHECKOUT_SAFE, &out);
891              
892 25           git_flag_opt(
893             strategy,
894             "recreate_missing",
895             GIT_CHECKOUT_RECREATE_MISSING, &out
896             );
897              
898 25           git_flag_opt(
899             strategy, "allow_conflicts",
900             GIT_CHECKOUT_ALLOW_CONFLICTS, &out
901             );
902              
903 25           git_flag_opt(
904             strategy, "remove_untracked",
905             GIT_CHECKOUT_REMOVE_UNTRACKED, &out
906             );
907              
908 25           git_flag_opt(
909             strategy, "remove_ignored",
910             GIT_CHECKOUT_REMOVE_IGNORED, &out
911             );
912              
913 25           git_flag_opt(strategy, "update_only", GIT_CHECKOUT_UPDATE_ONLY, &out);
914              
915 25           git_flag_opt(
916             strategy, "dont_update_index",
917             GIT_CHECKOUT_DONT_UPDATE_INDEX, &out
918             );
919              
920 25           git_flag_opt(strategy, "no_refresh", GIT_CHECKOUT_NO_REFRESH, &out);
921              
922 25           git_flag_opt(
923             strategy, "skip_unmerged",
924             GIT_CHECKOUT_SKIP_UNMERGED, &out
925             );
926              
927 25           git_flag_opt(strategy, "use_ours", GIT_CHECKOUT_USE_OURS, &out);
928              
929 25           git_flag_opt(strategy, "use_theirs", GIT_CHECKOUT_USE_THEIRS, &out);
930              
931 25           git_flag_opt(
932             strategy, "disable_pathspec_match",
933             GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH, &out);
934              
935 25           git_flag_opt(
936             strategy, "skip_locked_directories",
937             GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES, &out);
938              
939 25           git_flag_opt(
940             strategy, "dont_overwrite_ignored",
941             GIT_CHECKOUT_DONT_OVERWRITE_IGNORED, &out);
942              
943 25           git_flag_opt(
944             strategy, "conflict_style_merge",
945             GIT_CHECKOUT_CONFLICT_STYLE_MERGE, &out);
946              
947 25           git_flag_opt(
948             strategy, "conflict_style_diff3",
949             GIT_CHECKOUT_CONFLICT_STYLE_DIFF3, &out);
950              
951 25           git_flag_opt(
952             strategy, "dont_remove_existing",
953             GIT_CHECKOUT_DONT_REMOVE_EXISTING, &out);
954              
955 25           git_flag_opt(
956             strategy, "dont_write_index",
957             GIT_CHECKOUT_DONT_WRITE_INDEX, &out);
958              
959 25           return out;
960             }
961              
962 14           STATIC git_diff_format_t git_sv_to_diff_format(SV *format) {
963 14           git_diff_format_t fmt = GIT_DIFF_FORMAT_PATCH;
964 14           const char *fmt_str = git_ensure_pv(format, "format");
965              
966 14 100         if (!strcmp(fmt_str, "patch"))
967 8           fmt = GIT_DIFF_FORMAT_PATCH;
968 6 100         else if (!strcmp(fmt_str, "patch_header"))
969 1           fmt = GIT_DIFF_FORMAT_PATCH_HEADER;
970 5 100         else if (!strcmp(fmt_str, "raw"))
971 1           fmt = GIT_DIFF_FORMAT_RAW;
972 4 100         else if (!strcmp(fmt_str, "name_only"))
973 1           fmt = GIT_DIFF_FORMAT_NAME_ONLY;
974 3 100         else if (!strcmp(fmt_str, "name_status"))
975 2           fmt = GIT_DIFF_FORMAT_NAME_STATUS;
976             else
977 1           croak_usage("Invalid format");
978              
979 13           return fmt;
980             }
981              
982 42           STATIC int git_diff_cb(const git_diff_delta *delta, const git_diff_hunk *hunk,
983             const git_diff_line *line, void *data) {
984 42           dSP;
985              
986 42           SV *coderef = data;
987              
988 42           ENTER;
989 42           SAVETMPS;
990              
991 42 50         PUSHMARK(SP);
992 42           switch (line -> origin) {
993             case GIT_DIFF_LINE_CONTEXT:
994 0 0         XPUSHs(sv_2mortal(newSVpv("ctx", 0)));
995 0           break;
996              
997             case GIT_DIFF_LINE_ADDITION:
998             case GIT_DIFF_LINE_ADD_EOFNL:
999 9 50         XPUSHs(sv_2mortal(newSVpv("add", 0)));
1000 9           break;
1001              
1002             case GIT_DIFF_LINE_DELETION:
1003             case GIT_DIFF_LINE_DEL_EOFNL:
1004 8 50         XPUSHs(sv_2mortal(newSVpv("del", 0)));
1005 8           break;
1006              
1007             case GIT_DIFF_LINE_FILE_HDR:
1008 17 50         XPUSHs(sv_2mortal(newSVpv("file", 0)));
1009 17           break;
1010              
1011             case GIT_DIFF_LINE_HUNK_HDR:
1012 8 50         XPUSHs(sv_2mortal(newSVpv("hunk", 0)));
1013 8           break;
1014              
1015             case GIT_DIFF_LINE_CONTEXT_EOFNL:
1016 0 0         XPUSHs(sv_2mortal(newSVpv("noeol", 0)));
1017 0           break;
1018              
1019             case GIT_DIFF_LINE_BINARY:
1020 0 0         XPUSHs(sv_2mortal(newSVpv("bin", 0)));
1021 0           break;
1022              
1023             default:
1024 0           croak_assert("Unexpected diff origin: %d", line -> origin);
1025 0           break;
1026             }
1027              
1028 42 50         XPUSHs(sv_2mortal(newSVpv(line -> content, line -> content_len)));
1029 42           PUTBACK;
1030              
1031 42           call_sv(coderef, G_DISCARD);
1032              
1033 42 50         FREETMPS;
1034 42           LEAVE;
1035              
1036 42           return 0;
1037             }
1038              
1039             typedef struct {
1040             Repository repo_ptr;
1041             SV *repo;
1042             SV *cb;
1043             int annotated;
1044             int lightweight;
1045             } git_foreach_payload;
1046              
1047 12           STATIC int git_config_foreach_cbb(const git_config_entry *entry, void *payload) {
1048 12           dSP;
1049 12           int rv = 0;
1050              
1051 12           ENTER;
1052 12           SAVETMPS;
1053              
1054 12 50         PUSHMARK(SP);
1055 12 50         mXPUSHs(newSVpv(entry -> name, 0));
1056 12 50         mXPUSHs(newSVpv(entry -> value, 0));
1057 12 50         mXPUSHs(newSVuv(entry -> level));
1058 12           PUTBACK;
1059              
1060 12           call_sv(((git_foreach_payload *) payload) -> cb, G_SCALAR);
1061              
1062 12           SPAGAIN;
1063              
1064 12 50         rv = POPi;
1065              
1066 12           PUTBACK;
1067 12 50         FREETMPS;
1068 12           LEAVE;
1069              
1070 12 100         if (rv != 0)
1071 1           rv = GIT_EUSER;
1072              
1073 12           return rv;
1074             }
1075              
1076 12           STATIC int git_stash_foreach_cb(size_t i, const char *msg, const git_oid *oid, void *p) {
1077 12           dSP;
1078 12           int rc, rv = 0;
1079 12           Commit c = NULL;
1080 12           SV *commit = NULL;
1081 12           git_foreach_payload *payload = (git_foreach_payload *) p;
1082              
1083 12           rc = git_commit_lookup(&c,
1084 12           payload -> repo_ptr -> repository, oid
1085             );
1086 12           git_check_error(rc);
1087              
1088 12           GIT_NEW_OBJ_WITH_MAGIC(
1089             commit, "Git::Raw::Commit", c, SvRV(payload -> repo)
1090             );
1091              
1092 12           ENTER;
1093 12           SAVETMPS;
1094              
1095 12 50         PUSHMARK(SP);
1096 12 50         mXPUSHs(newSVuv(i));
1097 12 50         mXPUSHs(newSVpv(msg, 0));
1098 12 50         mXPUSHs(commit);
1099 12           PUTBACK;
1100              
1101 12           call_sv(payload -> cb, G_EVAL|G_SCALAR);
1102              
1103 12           SPAGAIN;
1104              
1105 12 50         if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1106 1           rv = -1;
1107 1           (void) POPs;
1108             } else {
1109 11 50         rv = POPi;
1110 11 100         if (rv != 0)
1111 3           rv = GIT_EUSER;
1112             }
1113              
1114 12           PUTBACK;
1115 12 50         FREETMPS;
1116 12           LEAVE;
1117              
1118 12           return rv;
1119             }
1120              
1121 9           STATIC int git_tag_foreach_cbb(const char *name, git_oid *oid, void *payload) {
1122 9           dSP;
1123 9           int rv = 0;
1124 9           git_otype type = GIT_OBJ_ANY;
1125             git_object *tag;
1126              
1127 9           SV *cb_arg = NULL;
1128 9           git_foreach_payload *pl = payload;
1129              
1130 9           int rc = git_object_lookup(
1131 9           &tag, pl -> repo_ptr -> repository, oid, type
1132             );
1133 9           git_check_error(rc);
1134              
1135 9           type = git_object_type(tag);
1136              
1137 9 100         if (type == GIT_OBJ_TAG) {
1138 6 100         if (pl -> annotated) {
1139 5           GIT_NEW_OBJ_WITH_MAGIC(
1140             cb_arg, "Git::Raw::Tag", (void *) tag, SvRV(pl -> repo)
1141             );
1142             } else
1143 1           return 0;
1144 3 50         } else if (type == GIT_OBJ_COMMIT) {
1145 3           git_object_free(tag);
1146              
1147 3 100         if (pl -> lightweight) {
1148 2           Reference ref = NULL;
1149 2           rc = git_reference_lookup(&ref,
1150 2           pl -> repo_ptr -> repository, name
1151             );
1152 2           git_check_error(rc);
1153              
1154 2           GIT_NEW_OBJ_WITH_MAGIC(
1155             cb_arg, "Git::Raw::Reference", (void *) ref, SvRV(pl -> repo)
1156             );
1157             } else
1158 1           return 0;
1159             } else
1160 0           croak_assert("Unexpected tag, object type of %s", git_object_type2string(type));
1161              
1162 7           ENTER;
1163 7           SAVETMPS;
1164              
1165 7 50         PUSHMARK(SP);
1166 7 50         mXPUSHs(cb_arg);
1167 7           PUTBACK;
1168              
1169 7           call_sv(pl -> cb, G_SCALAR);
1170              
1171 7           SPAGAIN;
1172              
1173 7 50         rv = POPi;
1174              
1175 7           PUTBACK;
1176 7 50         FREETMPS;
1177 7           LEAVE;
1178              
1179 7 100         if (rv != 0)
1180 1           rv = GIT_EUSER;
1181              
1182 9           return rv;
1183             }
1184              
1185 0           STATIC int git_submodule_foreach_cb(git_submodule *sm, const char *name, void *p) {
1186 0           dSP;
1187 0           int rv = 0;
1188 0           git_foreach_payload *payload = (git_foreach_payload *) p;
1189              
1190 0           ENTER;
1191 0           SAVETMPS;
1192              
1193 0 0         PUSHMARK(SP);
1194 0 0         mXPUSHs(newSVpv(name, 0));
1195 0           PUTBACK;
1196              
1197 0           call_sv(((git_foreach_payload *) payload) -> cb, G_SCALAR);
1198              
1199 0           SPAGAIN;
1200              
1201 0 0         rv = POPi;
1202              
1203 0           PUTBACK;
1204 0 0         FREETMPS;
1205 0           LEAVE;
1206              
1207 0 0         if (rv != 0)
1208 0           rv = GIT_EUSER;
1209              
1210 0           return rv;
1211             }
1212              
1213 2           STATIC int git_checkout_notify_cbb(git_checkout_notify_t why, const char *path, const git_diff_file *baseline,
1214             const git_diff_file *target, const git_diff_file *workdir, void *payload) {
1215 2           dSP;
1216              
1217 2           int rv = 0;
1218 2           AV *w = newAV();
1219              
1220             if (why & GIT_CHECKOUT_NOTIFY_NONE)
1221             av_push(w, newSVpv("none", 0));
1222              
1223 2 50         if (why & GIT_CHECKOUT_NOTIFY_CONFLICT)
1224 0           av_push(w, newSVpv("conflict", 0));
1225              
1226 2 50         if (why & GIT_CHECKOUT_NOTIFY_DIRTY)
1227 0           av_push(w, newSVpv("dirty", 0));
1228              
1229 2 100         if (why & GIT_CHECKOUT_NOTIFY_UPDATED)
1230 1           av_push(w, newSVpv("updated", 0));
1231              
1232 2 100         if (why & GIT_CHECKOUT_NOTIFY_UNTRACKED)
1233 1           av_push(w, newSVpv("untracked", 0));
1234              
1235 2 50         if (why & GIT_CHECKOUT_NOTIFY_IGNORED)
1236 0           av_push(w, newSVpv("ignored", 0));
1237              
1238 2           ENTER;
1239 2           SAVETMPS;
1240              
1241 2 50         PUSHMARK(SP);
1242 2 50         mXPUSHs(newSVpv(path, 0));
1243 2 50         mXPUSHs(newRV_noinc((SV *) w));
1244 2           PUTBACK;
1245              
1246 2           call_sv(payload, G_SCALAR);
1247              
1248 2           SPAGAIN;
1249              
1250 2 50         rv = POPi;
1251              
1252 2           PUTBACK;
1253 2 50         FREETMPS;
1254 2           LEAVE;
1255              
1256 2           return rv;
1257             }
1258              
1259 3           STATIC void git_checkout_progress_cbb(const char *path, size_t completed_steps,
1260             size_t total_steps, void *payload) {
1261 3           dSP;
1262              
1263 3           SV *coderef = payload;
1264              
1265 3           ENTER;
1266 3           SAVETMPS;
1267              
1268 3 50         PUSHMARK(SP);
1269 3 50         mXPUSHs(path ? newSVpv(path, 0) : &PL_sv_undef);
    100          
1270 3 50         mXPUSHs(newSViv(completed_steps));
1271 3 50         mXPUSHs(newSViv(total_steps));
1272 3           PUTBACK;
1273              
1274 3           call_sv(coderef, G_DISCARD);
1275              
1276 3           SPAGAIN;
1277              
1278 3           PUTBACK;
1279 3 50         FREETMPS;
1280 3           LEAVE;
1281 3           }
1282              
1283 0           STATIC int git_sideband_progress_cbb(const char *str, int len, void *cbs) {
1284 0           dSP;
1285              
1286 0           ENTER;
1287 0           SAVETMPS;
1288              
1289 0 0         PUSHMARK(SP);
1290 0 0         mXPUSHs(newSVpv(str, len));
1291 0           PUTBACK;
1292              
1293 0           call_sv(git_hv_code_entry((HV *)cbs, "sideband_progress"), G_DISCARD);
1294              
1295 0 0         FREETMPS;
1296 0           LEAVE;
1297              
1298 0           return 0;
1299             }
1300              
1301 5           STATIC int git_transfer_progress_cbb(const git_transfer_progress *stats, void *cbs) {
1302 5           dSP;
1303              
1304             SV *sv;
1305             git_transfer_progress *tp;
1306 5           Newx(tp, 1, git_transfer_progress);
1307 5           Copy(stats, tp, 1, git_transfer_progress);
1308              
1309 5           GIT_NEW_OBJ(
1310             sv, "Git::Raw::TransferProgress", tp
1311             );
1312              
1313 5           ENTER;
1314 5           SAVETMPS;
1315              
1316 5 50         PUSHMARK(SP);
1317 5 50         mXPUSHs(sv);
1318 5           PUTBACK;
1319              
1320 5           call_sv(git_hv_code_entry((HV *)cbs, "transfer_progress"), G_DISCARD);
1321              
1322 5 50         FREETMPS;
1323 5           LEAVE;
1324              
1325 5           return 0;
1326             }
1327              
1328 0           STATIC int git_push_transfer_progress_cbb(unsigned int current, unsigned int total, size_t bytes, void *cbs) {
1329 0           dSP;
1330              
1331 0           ENTER;
1332 0           SAVETMPS;
1333              
1334 0 0         PUSHMARK(SP);
1335 0 0         mXPUSHs(newSVuv(current));
1336 0 0         mXPUSHs(newSVuv(total));
1337 0 0         mXPUSHs(newSVuv(bytes));
1338 0           PUTBACK;
1339              
1340 0           call_sv(git_hv_code_entry((HV *)cbs, "push_transfer_progress"), G_VOID|G_DISCARD);
1341              
1342 0 0         FREETMPS;
1343 0           LEAVE;
1344              
1345 0           return 0;
1346             }
1347              
1348 9           STATIC int git_packbuilder_progress_cbb(int stage, unsigned int current, unsigned int total, void *cbs) {
1349 9           dSP;
1350              
1351 9           ENTER;
1352 9           SAVETMPS;
1353              
1354 9 50         PUSHMARK(SP);
1355 9 50         mXPUSHs(newSViv(stage));
1356 9 50         mXPUSHs(newSVuv(current));
1357 9 50         mXPUSHs(newSVuv(total));
1358 9           PUTBACK;
1359              
1360 9           call_sv(git_hv_code_entry((HV *)cbs, "pack_progress"), G_VOID|G_DISCARD);
1361              
1362 9 50         FREETMPS;
1363 9           LEAVE;
1364              
1365 9           return 0;
1366             }
1367              
1368 1           STATIC int git_push_update_reference_cbb(const char *ref, const char *msg, void *cbs) {
1369 1           dSP;
1370 1           int rv = 0;
1371              
1372 1 50         if (msg != NULL) {
1373 0           rv = GIT_EUSER;
1374             }
1375              
1376 1           ENTER;
1377 1           SAVETMPS;
1378              
1379 1 50         PUSHMARK(SP);
1380 1 50         mXPUSHs(newSVpv(ref, 0));
1381 1 50         mXPUSHs(newSVpv(msg, 0));
1382 1           PUTBACK;
1383              
1384 1           call_sv(git_hv_code_entry((HV *)cbs, "push_update_reference"), G_VOID|G_DISCARD);
1385              
1386 1 50         FREETMPS;
1387 1           LEAVE;
1388              
1389 1           return rv;
1390             }
1391              
1392 0           STATIC int git_push_negotiation_cbb(const git_push_update **updates, size_t len, void *cbs) {
1393 0           dSP;
1394 0           int rv = 0;
1395 0           size_t i = 0;
1396              
1397 0           AV *u = newAV();
1398 0 0         for (i = 0; i < len; ++i) {
1399 0           const git_push_update *update = updates[i];
1400              
1401 0           HV *value = newHV();
1402 0           hv_stores(value, "src_refname", newSVpv(update->src_refname, 0));
1403 0           hv_stores(value, "dst_refname", newSVpv(update->dst_refname, 0));
1404 0           hv_stores(value, "src", git_oid_to_sv(&update->src));
1405 0           hv_stores(value, "dst", git_oid_to_sv(&update->dst));
1406 0           av_push(u, newRV_noinc((SV *)value));
1407             }
1408              
1409 0           ENTER;
1410 0           SAVETMPS;
1411              
1412 0 0         PUSHMARK(SP);
1413 0 0         mXPUSHs(newRV_noinc((SV *)u));
1414 0           PUTBACK;
1415              
1416 0           call_sv(git_hv_code_entry((HV *)cbs, "push_negotiation"), G_EVAL|G_SCALAR);
1417              
1418 0           SPAGAIN;
1419              
1420 0 0         if (SvTRUE(ERRSV)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1421 0           rv = -1;
1422 0           (void) POPs;
1423             } else
1424 0 0         rv = POPi;
1425              
1426 0           PUTBACK;
1427 0 0         FREETMPS;
1428 0           LEAVE;
1429              
1430 0           return rv;
1431             }
1432              
1433 0           STATIC int git_transport_cbb(git_transport **out, git_remote *owner, void *cbs) {
1434 0           dSP;
1435              
1436 0           int rv = 0;
1437 0           Remote remote = NULL;
1438 0           SV *remote_sv = NULL;
1439              
1440 0           Newxz(remote, 1, git_raw_remote);
1441 0           git_remote_dup(&remote -> remote, owner);
1442 0           remote -> owned = 1;
1443              
1444 0           GIT_NEW_OBJ(
1445             remote_sv, "Git::Raw::Remote", remote
1446             );
1447              
1448 0           ENTER;
1449 0           SAVETMPS;
1450              
1451 0 0         PUSHMARK(SP);
1452 0 0         mXPUSHs(remote_sv);
1453 0           PUTBACK;
1454              
1455 0           call_sv(git_hv_code_entry((HV *)cbs, "transport"), G_EVAL|G_SCALAR);
1456              
1457 0           SPAGAIN;
1458              
1459 0 0         if (SvTRUE(ERRSV)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1460 0           rv = -1;
1461 0           (void) POPs;
1462              
1463 0           *out = NULL;
1464             } else {
1465             /* TODO: assign the transport */
1466 0           *out = NULL;
1467             }
1468              
1469 0           PUTBACK;
1470 0 0         FREETMPS;
1471 0           LEAVE;
1472              
1473 0           return rv;
1474             }
1475              
1476 0           STATIC int git_update_tips_cbb(const char *name, const git_oid *a,
1477             const git_oid *b, void *cbs) {
1478 0           dSP;
1479              
1480 0           ENTER;
1481 0           SAVETMPS;
1482              
1483 0 0         PUSHMARK(SP);
1484 0 0         mXPUSHs(newSVpv(name, 0));
1485 0 0         XPUSHs((a != NULL && !git_oid_iszero(a)) ? sv_2mortal(git_oid_to_sv(a)) : &PL_sv_undef);
    0          
    0          
1486 0 0         XPUSHs((b != NULL && !git_oid_iszero(b)) ? sv_2mortal(git_oid_to_sv(b)) : &PL_sv_undef);
    0          
    0          
1487 0           PUTBACK;
1488              
1489 0           call_sv(git_hv_code_entry((HV *)cbs, "update_tips"), G_DISCARD);
1490              
1491 0 0         FREETMPS;
1492 0           LEAVE;
1493              
1494 0           return 0;
1495             }
1496              
1497 0           STATIC int git_remote_create_cbb(git_remote **out, git_repository *r,
1498             const char *name, const char *url, void *cb) {
1499 0           dSP;
1500 0           int rv = 0;
1501 0           SV *repo_sv = NULL;
1502 0           Repository repo = NULL;
1503              
1504 0           Newxz(repo, 1, git_raw_repository);
1505 0           repo -> repository = r;
1506 0           repo -> owned = 0;
1507              
1508 0           GIT_NEW_OBJ(repo_sv,
1509             "Git::Raw::Repository",
1510             (void * ) repo
1511             );
1512              
1513 0           ENTER;
1514 0           SAVETMPS;
1515              
1516 0 0         PUSHMARK(SP);
1517 0 0         mXPUSHs(repo_sv);
1518 0 0         mXPUSHs(newSVpv(name, 0));
1519 0 0         mXPUSHs(newSVpv(url, 0));
1520 0           PUTBACK;
1521              
1522 0           call_sv((SV *) cb, G_EVAL|G_SCALAR);
1523              
1524 0           SPAGAIN;
1525              
1526 0 0         if (SvTRUE(ERRSV)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1527 0           rv = -1;
1528 0           (void) POPs;
1529              
1530 0           *out = NULL;
1531             } else {
1532 0           SV *r = POPs;
1533 0 0         if (SvOK(r)) {
    0          
    0          
1534 0           Remote remote = GIT_SV_TO_PTR(Remote, r);
1535 0           *out = remote -> remote;
1536              
1537             /* The remote created in the callback is owned by libgit2 */
1538 0           remote -> owned = 0;
1539             } else {
1540 0           *out = NULL;
1541 0           rv = -1;
1542             }
1543             }
1544              
1545 0           PUTBACK;
1546 0 0         FREETMPS;
1547 0           LEAVE;
1548              
1549 0           return rv;
1550             }
1551              
1552 0           STATIC int git_credentials_cbb(git_cred **cred, const char *url,
1553             const char *usr_from_url, unsigned int allow, void *cbs) {
1554 0           dSP;
1555 0           int rv = 0;
1556 0           AV *types = newAV();
1557             Cred creds;
1558              
1559 0 0         if (allow & GIT_CREDTYPE_USERPASS_PLAINTEXT)
1560 0           av_push(types, newSVpv("userpass_plaintext", 0));
1561 0 0         if (allow & GIT_CREDTYPE_SSH_KEY)
1562 0           av_push(types, newSVpv("ssh_key", 0));
1563 0 0         if (allow & GIT_CREDTYPE_SSH_CUSTOM)
1564 0           av_push(types, newSVpv("ssh_custom", 0));
1565 0 0         if (allow & GIT_CREDTYPE_DEFAULT)
1566 0           av_push(types, newSVpv("default", 0));
1567 0 0         if (allow & GIT_CREDTYPE_SSH_INTERACTIVE)
1568 0           av_push(types, newSVpv("ssh_interactive", 0));
1569 0 0         if (allow & GIT_CREDTYPE_USERNAME)
1570 0           av_push(types, newSVpv("username", 0));
1571 0 0         if (allow & GIT_CREDTYPE_SSH_MEMORY)
1572 0           av_push(types, newSVpv("ssh_memory", 0));
1573              
1574 0           ENTER;
1575 0           SAVETMPS;
1576              
1577 0 0         PUSHMARK(SP);
1578 0 0         mXPUSHs(newSVpv(url, 0));
1579 0 0         mXPUSHs(newSVpv(usr_from_url, 0));
1580 0 0         mXPUSHs(newRV_noinc((SV *)types));
1581 0           PUTBACK;
1582              
1583 0           call_sv(git_hv_code_entry((HV *)cbs, "credentials"), G_EVAL|G_SCALAR);
1584              
1585 0           SPAGAIN;
1586              
1587 0 0         if (SvTRUE(ERRSV)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1588 0           rv = GIT_PASSTHROUGH;
1589 0           (void) POPs;
1590             } else {
1591 0           SV *c = POPs;
1592 0 0         if (SvOK(c)) {
    0          
    0          
1593 0           creds = GIT_SV_TO_PTR(Cred, c);
1594 0           *cred = creds -> cred;
1595             } else
1596 0           rv = GIT_PASSTHROUGH;
1597             }
1598              
1599 0           PUTBACK;
1600 0 0         FREETMPS;
1601 0           LEAVE;
1602              
1603 0           return rv;
1604             }
1605              
1606 0           STATIC int git_certificate_check_cbb(git_cert *cert, int valid, const char *host, void *cbs) {
1607 0           dSP;
1608 0           int rv = 0;
1609 0           SV *obj = NULL;
1610              
1611 0 0         if (cert -> cert_type == GIT_CERT_X509) {
1612 0           git_cert_x509 *x509 = (git_cert_x509 *) cert;
1613              
1614 0           GIT_NEW_OBJ(
1615             obj, "Git::Raw::Cert::X509", (void *) x509
1616             );
1617 0 0         } else if (cert -> cert_type == GIT_CERT_HOSTKEY_LIBSSH2) {
1618 0           git_cert_hostkey *ssh = (git_cert_hostkey *) cert;
1619              
1620 0           GIT_NEW_OBJ(
1621             obj, "Git::Raw::Cert::HostKey", (void *) ssh
1622             );
1623             }
1624              
1625 0           ENTER;
1626 0           SAVETMPS;
1627              
1628 0 0         PUSHMARK(SP);
1629 0 0         mXPUSHs(obj);
1630 0 0         mXPUSHs(newSViv(valid));
1631 0 0         mXPUSHs(newSVpv(host, 0));
1632 0           PUTBACK;
1633              
1634 0           call_sv(git_hv_code_entry((HV *)cbs, "certificate_check"), G_EVAL|G_SCALAR);
1635              
1636 0           SPAGAIN;
1637              
1638 0 0         if (SvTRUE(ERRSV)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1639 0           rv = -1;
1640 0           (void) POPs;
1641             } else
1642 0 0         rv = POPi;
1643              
1644 0           PUTBACK;
1645 0 0         FREETMPS;
1646 0           LEAVE;
1647              
1648 0           return rv;
1649             }
1650              
1651 0           STATIC void git_ssh_interactive_cbb(const char *name, int name_len, const char *instruction, int instruction_len,
1652             int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) {
1653 0           dSP;
1654              
1655             int i, count;
1656 0           SV *cb = *abstract;
1657              
1658 0 0         if (num_prompts == 0)
1659 0           return;
1660              
1661 0           ENTER;
1662 0           SAVETMPS;
1663              
1664 0 0         PUSHMARK(SP);
1665 0 0         mXPUSHs(newSVpv(name, name_len));
1666 0 0         mXPUSHs(newSVpv(instruction, instruction_len));
1667 0 0         for (i = 0; i < num_prompts; ++i) {
1668 0           HV *prompt = newHV();
1669 0           hv_stores(prompt, "text", newSVpvn(prompts[i].text, prompts[i].length));
1670 0           hv_stores(prompt, "echo", newSViv(prompts[i].echo));
1671 0 0         mXPUSHs(newRV_noinc((SV*)prompt));
1672             }
1673 0           PUTBACK;
1674              
1675 0           count = call_sv(cb, G_ARRAY);
1676              
1677 0           SPAGAIN;
1678              
1679 0 0         if (count != num_prompts)
1680 0           croak_usage("Expected %d response(s) got %d", num_prompts, count);
1681              
1682 0 0         for (i = 1; i <= count; ++i) {
1683             STRLEN len;
1684 0           SV *r = POPs;
1685 0 0         const char *response = SvPV(r, len);
1686 0           int index = num_prompts - i;
1687              
1688 0           Newxz(responses[index].text, len, char);
1689 0           Copy(response, responses[index].text, len, char);
1690 0           responses[index].length = len;
1691             }
1692              
1693 0           PUTBACK;
1694 0 0         FREETMPS;
1695 0           LEAVE;
1696             }
1697              
1698 1           STATIC int git_filter_init_cbb(git_filter *filter) {
1699 1           dSP;
1700              
1701 1           int rv = 0;
1702              
1703 1           ENTER;
1704 1           SAVETMPS;
1705              
1706 1 50         PUSHMARK(SP);
1707 1           PUTBACK;
1708              
1709 1           call_sv(((git_raw_filter *) filter) -> callbacks.initialize, G_EVAL|G_SCALAR);
1710              
1711 1           SPAGAIN;
1712              
1713 1 50         if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1714 0           rv = GIT_EUSER;
1715 0           (void) POPs;
1716             } else {
1717 1 50         rv = POPi;
1718             }
1719              
1720 1           PUTBACK;
1721 1 50         FREETMPS;
1722 1           LEAVE;
1723              
1724 1           return rv;
1725             }
1726              
1727 2           STATIC void git_filter_shutdown_cbb(git_filter *filter) {
1728 2           dSP;
1729              
1730 2           ENTER;
1731 2           SAVETMPS;
1732              
1733 2 50         PUSHMARK(SP);
1734 2           PUTBACK;
1735              
1736 2           call_sv(((git_raw_filter *) filter) -> callbacks.shutdown, G_DISCARD);
1737              
1738 2 50         FREETMPS;
1739 2           LEAVE;
1740 2           }
1741              
1742 5           STATIC int git_filter_check_cbb(git_filter *filter, void **payload,
1743             const git_filter_source *src, const char **attr_values) {
1744 5           dSP;
1745              
1746 5           int rv = 0;
1747 5           SV *filter_source = NULL;
1748              
1749 5           GIT_NEW_OBJ(
1750             filter_source, "Git::Raw::Filter::Source", (void *) src
1751             );
1752              
1753 5           ENTER;
1754 5           SAVETMPS;
1755              
1756 5 50         PUSHMARK(SP);
1757 5 50         mXPUSHs(filter_source);
1758 5           PUTBACK;
1759              
1760 5           call_sv(((git_raw_filter *) filter) -> callbacks.check, G_EVAL|G_SCALAR);
1761              
1762 5           SPAGAIN;
1763              
1764 5 50         if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1765 0           rv = GIT_EUSER;
1766 0           (void) POPs;
1767             } else {
1768 5 50         rv = POPi;
1769             }
1770              
1771 5           PUTBACK;
1772 5 50         FREETMPS;
1773 5           LEAVE;
1774              
1775 5           return rv;
1776             }
1777              
1778 4           STATIC int git_filter_apply_cbb(git_filter *filter, void **payload,
1779             git_buf *to, const git_buf *from, const git_filter_source *src) {
1780 4           dSP;
1781              
1782             int rv;
1783 4           SV *filter_source = NULL;
1784 4           SV *result = newSV(from -> size);
1785              
1786 4           GIT_NEW_OBJ(
1787             filter_source, "Git::Raw::Filter::Source", (void *) src
1788             );
1789              
1790 4           ENTER;
1791 4           SAVETMPS;
1792              
1793 4 50         PUSHMARK(SP);
1794 4 50         mXPUSHs(filter_source);
1795 4 50         mXPUSHs(newSVpv(from -> ptr, from -> size));
1796 4 50         mXPUSHs(newRV_noinc(result));
1797 4           PUTBACK;
1798              
1799 4           call_sv(((git_raw_filter *) filter) -> callbacks.apply, G_EVAL|G_SCALAR);
1800              
1801 4           SPAGAIN;
1802              
1803 4 50         if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1804 1           rv = GIT_EUSER;
1805 1           (void) POPs;
1806             } else {
1807 3 50         rv = POPi;
1808             }
1809              
1810 4 100         if (rv == GIT_OK) {
1811             STRLEN len;
1812 2 50         const char *ptr = SvPV(result, len);
1813              
1814 2           git_buf_set(to, ptr, len);
1815             }
1816              
1817 4           PUTBACK;
1818 4 50         FREETMPS;
1819 4           LEAVE;
1820              
1821 4           return rv;
1822             }
1823              
1824 1           STATIC void git_filter_cleanup_cbb(git_filter *filter, void *payload) {
1825 1           dSP;
1826              
1827 1           ENTER;
1828 1           SAVETMPS;
1829              
1830 1 50         PUSHMARK(SP);
1831 1           PUTBACK;
1832              
1833 1           call_sv(((git_raw_filter *) filter) -> callbacks.cleanup, G_DISCARD);
1834              
1835 1 50         FREETMPS;
1836 1           LEAVE;
1837 1           }
1838              
1839 7           STATIC int git_index_matched_path_cbb(const char *path, const char *pathspec, void *payload) {
1840 7           dSP;
1841              
1842 7           int rv = 0;
1843 7           SV *callback = (SV *) payload;
1844              
1845 7 100         if (callback == NULL)
1846 2           return rv;
1847              
1848 5           ENTER;
1849 5           SAVETMPS;
1850              
1851 5 50         PUSHMARK(SP);
1852 5 50         mXPUSHs(newSVpv(path, 0));
1853 5 50         mXPUSHs(pathspec ? newSVpv(pathspec, 0) : &PL_sv_undef);
    50          
1854 5           PUTBACK;
1855              
1856 5           call_sv(callback, G_SCALAR|G_EVAL);
1857              
1858 5           SPAGAIN;
1859              
1860 5 50         if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1861 1           rv = -1;
1862 1           (void) POPs;
1863             } else
1864 4 50         rv = POPi;
1865              
1866 5           PUTBACK;
1867 5 50         FREETMPS;
1868 5           LEAVE;
1869              
1870 5           return rv;
1871             }
1872              
1873 10           STATIC int git_stash_apply_progress_cbb(git_stash_apply_progress_t progress, void *payload)
1874             {
1875 10           dSP;
1876 10           int rv = 0;
1877 10           SV *callback = (SV *) payload;
1878              
1879 10 50         if (callback == NULL)
1880 0           return rv;
1881              
1882 10           ENTER;
1883 10           SAVETMPS;
1884              
1885 10 50         PUSHMARK(SP);
1886 10 50         mXPUSHs(newSViv (progress));
1887 10           PUTBACK;
1888              
1889 10           call_sv(callback, G_VOID|G_EVAL);
1890              
1891 10           SPAGAIN;
1892              
1893 10 50         if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
1894 0           rv = -1;
1895 0           (void) POPs;
1896             }
1897              
1898 10           PUTBACK;
1899 10 50         FREETMPS;
1900 10           LEAVE;
1901              
1902 10           return rv;
1903             }
1904              
1905 121           STATIC int git_odb_foreach_cbb(const git_oid *oid, void *payload) {
1906 121           dSP;
1907 121           int rv = 0;
1908              
1909 121           ENTER;
1910 121           SAVETMPS;
1911              
1912 121 50         PUSHMARK(SP);
1913 121 50         mXPUSHs(git_oid_to_sv(oid));
1914 121           PUTBACK;
1915              
1916 121           call_sv((SV *)payload, G_EVAL|G_SCALAR);
1917              
1918 121           SPAGAIN;
1919              
1920 121 50         if (SvTRUE(ERRSV)) {
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1921 0           rv = -1;
1922 0           (void) POPs;
1923             } else {
1924 121 50         rv = POPi;
1925 121 50         if (rv != 0)
1926 0           rv = GIT_EUSER;
1927             }
1928              
1929 121           PUTBACK;
1930 121 50         FREETMPS;
1931 121           LEAVE;
1932              
1933 121           return rv;
1934             }
1935              
1936 11           STATIC void git_list_to_paths(AV *list, git_strarray *paths) {
1937 11           size_t i = 0, count = 0;
1938             SV **path;
1939              
1940 23 100         while ((path = av_fetch(list, i++, 0))) {
1941 12 50         if (!path || !SvOK(*path))
    100          
    50          
    50          
1942 1           continue;
1943              
1944 11 50         Renew(paths->strings, count + 1, char *);
1945 11 50         paths->strings[count++] = SvPVbyte_nolen(*path);
1946             }
1947              
1948 11           paths->count = count;
1949 11           }
1950              
1951 0           STATIC void git_hv_to_clone_opts(HV *opts, git_clone_options *clone_opts) {
1952             SV *opt;
1953             HV *callbacks;
1954              
1955 0 0         if ((opt = git_hv_int_entry(opts, "bare")) && SvIV(opt))
    0          
    0          
1956 0           clone_opts->bare = 1;
1957              
1958 0 0         if ((opt = git_hv_string_entry(opts, "checkout_branch")))
1959 0           clone_opts->checkout_branch = git_ensure_pv(opt, "checkout_branch");
1960              
1961 0 0         if ((opt = git_hv_int_entry(opts, "disable_checkout")) && SvIV(opt))
    0          
    0          
1962 0           clone_opts->checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
1963              
1964             /* Callbacks */
1965 0 0         if ((callbacks = git_hv_hash_entry(opts, "callbacks"))) {
1966 0           SV *remote_cb = NULL;
1967              
1968 0 0         if ((remote_cb = get_callback_option(callbacks, "remote_create"))) {
1969 0           clone_opts->remote_cb = git_remote_create_cbb;
1970 0           clone_opts->remote_cb_payload = remote_cb;
1971             }
1972             }
1973 0           }
1974              
1975 33           STATIC void git_hv_to_checkout_opts(HV *opts, git_checkout_options *checkout_opts) {
1976 33           char **paths = NULL;
1977             SV *opt;
1978             HV *hopt;
1979             AV *lopt;
1980              
1981 33 100         if ((hopt = git_hv_hash_entry(opts, "checkout_strategy")))
1982 25           checkout_opts -> checkout_strategy =
1983 25           git_hv_to_checkout_strategy(hopt);
1984              
1985 33 100         if ((lopt = git_hv_list_entry(opts, "paths"))) {
1986             SV **path;
1987 2           size_t i = 0, count = 0;
1988              
1989 6 100         while ((path = av_fetch(lopt, i++, 0))) {
1990 4 100         if (!SvOK(*path))
    50          
    50          
1991 1           continue;
1992              
1993 3 50         Renew(paths, count+1, char *);
1994 3 50         paths[count++] = SvPVbyte_nolen(*path);
1995             }
1996              
1997 2 50         if (count > 0) {
1998 2           checkout_opts -> paths.strings = paths;
1999 2           checkout_opts -> paths.count = count;
2000             }
2001             }
2002              
2003 33 50         if ((opt = git_hv_string_entry(opts, "target_directory")))
2004 0 0         checkout_opts -> target_directory = SvPVbyte_nolen(opt);
2005              
2006 33 100         if ((opt = git_hv_string_entry(opts, "ancestor_label")))
2007 1 50         checkout_opts -> ancestor_label = SvPVbyte_nolen(opt);
2008              
2009 33 100         if ((opt = git_hv_string_entry(opts, "our_label")))
2010 1 50         checkout_opts -> our_label = SvPVbyte_nolen(opt);
2011              
2012 33 100         if ((opt = git_hv_string_entry(opts, "their_label")))
2013 1 50         checkout_opts -> their_label = SvPVbyte_nolen(opt);
2014              
2015 33 100         if ((hopt = git_hv_hash_entry(opts, "callbacks"))) {
2016 1 50         if ((checkout_opts -> progress_payload =
2017 1           get_callback_option(hopt, "progress")))
2018 1           checkout_opts -> progress_cb = git_checkout_progress_cbb;
2019              
2020 1 50         if ((checkout_opts -> notify_payload =
2021 1           get_callback_option(hopt, "notify"))) {
2022 1           checkout_opts -> notify_cb = git_checkout_notify_cbb;
2023              
2024 1 50         if ((lopt = git_hv_list_entry(opts, "notify"))) {
2025 1           size_t count = 0;
2026             SV **flag;
2027              
2028 7 100         while ((flag = av_fetch(lopt, count++, 0))) {
2029 6 50         if (SvPOK(*flag)) {
2030 6 50         const char *f = SvPVbyte_nolen(*flag);
2031              
2032 6 100         if (strcmp(f, "conflict") == 0)
2033 1           checkout_opts -> notify_flags |= GIT_CHECKOUT_NOTIFY_CONFLICT;
2034              
2035 6 100         if (strcmp(f, "dirty") == 0)
2036 1           checkout_opts -> notify_flags |= GIT_CHECKOUT_NOTIFY_DIRTY;
2037              
2038 6 100         if (strcmp(f, "updated") == 0)
2039 1           checkout_opts -> notify_flags |= GIT_CHECKOUT_NOTIFY_UPDATED;
2040              
2041 6 100         if (strcmp(f, "untracked") == 0)
2042 1           checkout_opts -> notify_flags |= GIT_CHECKOUT_NOTIFY_UNTRACKED;
2043              
2044 6 100         if (strcmp(f, "ignored") == 0)
2045 1           checkout_opts -> notify_flags |= GIT_CHECKOUT_NOTIFY_IGNORED;
2046              
2047 6 100         if (strcmp(f, "all") == 0)
2048 6           checkout_opts -> notify_flags |= GIT_CHECKOUT_NOTIFY_ALL;
2049             } else
2050 0           croak_usage("Invalid type for 'notify' value");
2051             }
2052             }
2053             }
2054             }
2055 33           }
2056              
2057 14           STATIC void git_hv_to_diff_opts(HV *opts, git_diff_options *diff_options, git_tree **tree) {
2058             SV *opt;
2059             HV *hopt;
2060             AV *lopt;
2061              
2062 14 100         if (tree) {
2063 12           *tree = NULL;
2064              
2065 12 50         if ((opt = git_hv_sv_entry(opts, "tree")) && SvOK(opt))
    50          
    0          
    0          
2066 12           *tree = GIT_SV_TO_PTR(Tree, opt);
2067             }
2068              
2069 14 100         if ((hopt = git_hv_hash_entry(opts, "flags")))
2070 5           diff_options->flags |= git_hv_to_diff_flag(hopt);
2071              
2072 14 100         if ((hopt = git_hv_hash_entry(opts, "prefix"))) {
2073             SV *ab;
2074              
2075 3 50         if ((ab = git_hv_string_entry(hopt, "a")))
2076 3 50         diff_options->old_prefix = SvPVbyte_nolen(ab);
2077              
2078 3 50         if ((ab = git_hv_string_entry(hopt, "b")))
2079 3 50         diff_options->new_prefix = SvPVbyte_nolen(ab);
2080             }
2081              
2082 14 100         if ((opt = git_hv_int_entry(opts, "context_lines")))
2083 2 50         diff_options->context_lines = (uint16_t) SvIV(opt);
2084              
2085 14 100         if ((opt = git_hv_int_entry(opts, "interhunk_lines")))
2086 2 50         diff_options->interhunk_lines = (uint16_t) SvIV(opt);
2087              
2088 14 100         if ((lopt = git_hv_list_entry(opts, "paths"))) {
2089             SV **path;
2090 5           char **paths = NULL;
2091 5           size_t i = 0, count = 0;
2092              
2093 13 100         while ((path = av_fetch(lopt, i++, 0))) {
2094 8 100         if (!SvOK(*path))
    50          
    50          
2095 2           continue;
2096              
2097 6 50         Renew(paths, count + 1, char *);
2098 6 50         paths[count++] = SvPVbyte_nolen(*path);
2099             }
2100              
2101 5 50         if (count > 0) {
2102 5           diff_options->flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
2103 5           diff_options->pathspec.strings = paths;
2104 5           diff_options->pathspec.count = count;
2105             }
2106             }
2107 14           }
2108              
2109 2           STATIC void git_hv_to_stash_apply_opts(HV *opts, git_stash_apply_options *stash_opts) {
2110             HV *hopt;
2111              
2112 2 50         if ((hopt = git_hv_hash_entry(opts, "checkout_opts")))
2113 0           git_hv_to_checkout_opts(hopt, &stash_opts->checkout_options);
2114              
2115 2 50         if ((hopt = git_hv_hash_entry(opts, "flags"))) {
2116 2           unsigned flags = 0;
2117              
2118 2           git_flag_opt(hopt, "reinstate_index", GIT_STASH_APPLY_REINSTATE_INDEX, &flags);
2119              
2120 2           stash_opts->flags = flags;
2121             }
2122              
2123 2 50         if ((hopt = git_hv_hash_entry(opts, "callbacks"))) {
2124 2 50         if ((stash_opts->progress_payload = get_callback_option(hopt, "apply_progress")))
2125 2           stash_opts->progress_cb = git_stash_apply_progress_cbb;
2126              
2127 2           SAVEFREESV(MUTABLE_SV(stash_opts->progress_payload));
2128             }
2129 2           }
2130              
2131 2           STATIC void git_hv_to_remote_callbacks(HV *opts, git_remote_callbacks *callbacks) {
2132 2           callbacks->payload = (void *)opts;
2133              
2134 2 50         if (get_callback_option(opts, "credentials"))
2135 0           callbacks->credentials = git_credentials_cbb;
2136              
2137 2 50         if (get_callback_option(opts, "certificate_check"))
2138 0           callbacks->certificate_check = git_certificate_check_cbb;
2139              
2140 2 50         if (get_callback_option(opts, "sideband_progress"))
2141 0           callbacks->sideband_progress = git_sideband_progress_cbb;
2142              
2143 2 50         if (get_callback_option(opts, "transfer_progress"))
2144 0           callbacks->transfer_progress = git_transfer_progress_cbb;
2145              
2146 2 50         if (get_callback_option(opts, "update_tips"))
2147 0           callbacks->update_tips = git_update_tips_cbb;
2148              
2149 2 50         if (get_callback_option(opts, "pack_progress"))
2150 2           callbacks->pack_progress = git_packbuilder_progress_cbb;
2151              
2152 2 50         if (get_callback_option(opts, "push_transfer_progress"))
2153 0           callbacks->push_transfer_progress = git_push_transfer_progress_cbb;
2154              
2155 2 100         if (get_callback_option(opts, "push_update_reference"))
2156 1           callbacks->push_update_reference = git_push_update_reference_cbb;
2157              
2158 2 50         if (get_callback_option(opts, "push_negotiation"))
2159 0           callbacks->push_negotiation = git_push_negotiation_cbb;
2160              
2161 2 50         if (get_callback_option(opts, "transport"))
2162 0           callbacks->transport = git_transport_cbb;
2163 2           }
2164              
2165 0           STATIC void git_hv_to_fetch_opts(HV *opts, git_fetch_options *fetch_opts) {
2166             HV *hopt;
2167              
2168 0 0         if ((hopt = git_hv_hash_entry(opts, "callbacks")))
2169 0           git_hv_to_remote_callbacks(hopt, &fetch_opts->callbacks);
2170 0           }
2171              
2172 2           STATIC void git_hv_to_push_opts(HV *opts, git_push_options *push_opts) {
2173             HV *hopt;
2174              
2175 2 50         if ((hopt = git_hv_hash_entry(opts, "callbacks")))
2176 2           git_hv_to_remote_callbacks(hopt, &push_opts->callbacks);
2177 2           }
2178              
2179 1           STATIC unsigned git_hv_to_merge_flag(HV *flags) {
2180 1           unsigned out = 0;
2181              
2182 1           git_flag_opt(flags, "find_renames", GIT_MERGE_FIND_RENAMES, &out);
2183              
2184 1           return out;
2185             }
2186              
2187 2           STATIC unsigned git_hv_to_merge_file_flag(HV *flags) {
2188 2           unsigned out = 0;
2189              
2190 2           git_flag_opt(flags, "merge", GIT_MERGE_FILE_STYLE_MERGE, &out);
2191 2           git_flag_opt(flags, "diff3", GIT_MERGE_FILE_STYLE_DIFF3, &out);
2192 2           git_flag_opt(flags, "simplify_alnum", GIT_MERGE_FILE_SIMPLIFY_ALNUM, &out);
2193              
2194 2           git_flag_opt(flags, "ignore_whitespace", GIT_MERGE_FILE_IGNORE_WHITESPACE, &out);
2195 2           git_flag_opt(flags, "ignore_whitespace_change", GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE, &out);
2196 2           git_flag_opt(flags, "ignore_whitespace_eol", GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL, &out);
2197              
2198 2           git_flag_opt(flags, "patience", GIT_MERGE_FILE_DIFF_PATIENCE, &out);
2199 2           git_flag_opt(flags, "minimal", GIT_MERGE_FILE_DIFF_MINIMAL, &out);
2200              
2201 2           return out;
2202             }
2203              
2204 14           STATIC void git_hv_to_merge_opts(HV *opts, git_merge_options *merge_options) {
2205             HV *hopt;
2206             SV *opt;
2207              
2208 14 100         if ((hopt = git_hv_hash_entry(opts, "flags")))
2209 1           merge_options -> flags |= git_hv_to_merge_flag(hopt);
2210              
2211 12 100         if ((hopt = git_hv_hash_entry(opts, "file_flags")))
2212 1           merge_options -> file_flags |= git_hv_to_merge_file_flag(hopt);
2213              
2214 12 100         if ((opt = git_hv_string_entry(opts, "favor"))) {
2215 3 50         const char *favor = SvPVbyte_nolen(opt);
2216 3 100         if (strcmp(favor, "ours") == 0)
2217 1           merge_options -> file_favor =
2218             GIT_MERGE_FILE_FAVOR_OURS;
2219 2 100         else if (strcmp(favor, "theirs") == 0)
2220 1           merge_options -> file_favor =
2221             GIT_MERGE_FILE_FAVOR_THEIRS;
2222 1 50         else if (strcmp(favor, "union") == 0)
2223 0           merge_options -> file_favor =
2224             GIT_MERGE_FILE_FAVOR_UNION;
2225             else
2226 1           croak_usage("Invalid 'favor' value");
2227             }
2228              
2229 11 100         if ((opt = git_hv_int_entry(opts, "rename_threshold")))
2230 1 50         merge_options -> rename_threshold = SvIV(opt);
2231              
2232 11 100         if ((opt = git_hv_int_entry(opts, "target_limit")))
2233 1 50         merge_options -> target_limit = SvIV(opt);
2234 11           }
2235              
2236 3           STATIC void git_hv_to_merge_file_opts(HV *opts, git_merge_file_options *merge_options) {
2237             AV *lopt;
2238             HV *hopt;
2239             SV *opt;
2240              
2241 3 100         if ((hopt = git_hv_hash_entry(opts, "flags")))
2242 1           merge_options -> flags |= git_hv_to_merge_file_flag(hopt);
2243              
2244 3 100         if ((opt = git_hv_string_entry(opts, "favor"))) {
2245 2 50         const char *favor = SvPVbyte_nolen(opt);
2246 2 100         if (strcmp(favor, "ours") == 0)
2247 1           merge_options -> favor =
2248             GIT_MERGE_FILE_FAVOR_OURS;
2249 1 50         else if (strcmp(favor, "theirs") == 0)
2250 0           merge_options -> favor =
2251             GIT_MERGE_FILE_FAVOR_THEIRS;
2252 1 50         else if (strcmp(favor, "union") == 0)
2253 0           merge_options -> favor =
2254             GIT_MERGE_FILE_FAVOR_UNION;
2255             else
2256 1           croak_usage("Invalid 'favor' value");
2257             }
2258              
2259 2 100         if ((opt = git_hv_string_entry(opts, "ancestor_label")))
2260 1 50         merge_options -> ancestor_label = SvPVbyte_nolen(opt);
2261              
2262 2 100         if ((opt = git_hv_string_entry(opts, "our_label")))
2263 1 50         merge_options -> our_label = SvPVbyte_nolen(opt);
2264              
2265 2 100         if ((opt = git_hv_string_entry(opts, "their_label")))
2266 1 50         merge_options -> their_label = SvPVbyte_nolen(opt);
2267              
2268 2 100         if ((opt = git_hv_int_entry(opts, "marker_size")))
2269 1 50         merge_options -> marker_size = SvIV(opt);
2270 2           }
2271              
2272 5           STATIC unsigned git_hv_to_worktree_prune_flag(HV *flags) {
2273 5           unsigned out = 0;
2274              
2275 5           git_flag_opt(flags, "valid", GIT_WORKTREE_PRUNE_VALID, &out);
2276 5           git_flag_opt(flags, "locked", GIT_WORKTREE_PRUNE_LOCKED, &out);
2277 5           git_flag_opt(flags, "working_tree", GIT_WORKTREE_PRUNE_WORKING_TREE, &out);
2278              
2279 5           return out;
2280             }
2281              
2282 6           STATIC void git_hv_to_worktree_prune_opts(HV *opts, git_worktree_prune_options *prune_options) {
2283             HV *hopt;
2284              
2285 6 100         if ((hopt = git_hv_hash_entry(opts, "flags")))
2286 5           prune_options -> flags |= git_hv_to_worktree_prune_flag(hopt);
2287 6           }
2288              
2289 3           STATIC void git_hv_to_rebase_opts(HV *opts, git_rebase_options *rebase_opts) {
2290             SV *opt;
2291             HV *hopt;
2292              
2293 3 100         if ((opt = git_hv_int_entry(opts, "quiet")))
2294 2 50         rebase_opts -> quiet = SvIV(opt);
2295              
2296 3 100         if ((opt = git_hv_int_entry(opts, "inmemory")))
2297 1 50         rebase_opts -> inmemory = SvIV(opt);
2298              
2299 3 50         if ((opt = git_hv_string_entry(opts, "rewrite_notes_ref")))
2300 0 0         rebase_opts -> rewrite_notes_ref = SvPVbyte_nolen(opt);
2301              
2302 3 100         if ((hopt = git_hv_hash_entry(opts, "merge_opts")))
2303 2           git_hv_to_merge_opts(hopt, &rebase_opts -> merge_options);
2304              
2305 3 100         if ((hopt = git_hv_hash_entry(opts, "checkout_opts")))
2306 2           git_hv_to_checkout_opts(hopt, &rebase_opts -> checkout_options);
2307 3           }
2308              
2309 0           STATIC void git_hv_to_submodule_update_opts(HV *opts, git_submodule_update_options *update_opts) {
2310             SV *opt;
2311             HV *hopt;
2312              
2313 0 0         if ((hopt = git_hv_hash_entry(opts, "fetch_opts")))
2314 0           git_hv_to_fetch_opts(hopt, &update_opts -> fetch_opts);
2315              
2316 0 0         if ((hopt = git_hv_hash_entry(opts, "checkout_opts")))
2317 0           git_hv_to_checkout_opts(hopt, &update_opts -> checkout_opts);
2318              
2319 0 0         if ((opt = git_hv_int_entry(opts, "allow_fetch")))
2320 0 0         update_opts -> allow_fetch = SvIV(opt);
2321 0           }
2322              
2323             MODULE = Git::Raw PACKAGE = Git::Raw
2324              
2325             BOOT:
2326 86           git_libgit2_init();
2327              
2328             SV *
2329             message_prettify(class, msg, ...)
2330             SV *class
2331             SV *msg
2332              
2333             PROTOTYPE: $;$$
2334             PREINIT:
2335 5           int rc, strip_comments = 1;
2336 5           char comment_char = '#';
2337              
2338 5           git_buf buf = GIT_BUF_INIT_CONST(NULL, 0);
2339             const char *message;
2340              
2341             CODE:
2342 5           message = git_ensure_pv(msg, "msg");
2343              
2344 5 50         if (items >= 3)
2345 5           strip_comments = (int) git_ensure_iv(ST(2), "strip_comments");
2346 5 50         if (items >= 4) {
2347             STRLEN len;
2348 5           const char *comment = git_ensure_pv_with_len(ST(3), "comment_char", &len);
2349              
2350 5 100         if (len != 1)
2351 1           croak_usage("Expected a single character for 'comment_char'");
2352              
2353 4           comment_char = comment[0];
2354             }
2355              
2356 4           rc = git_message_prettify(
2357             &buf, message, strip_comments, comment_char
2358             );
2359              
2360 4           RETVAL = &PL_sv_undef;
2361 4 50         if (rc == GIT_OK) {
2362 4           RETVAL = newSVpv(buf.ptr, buf.size);
2363 4           git_buf_dispose(&buf);
2364             }
2365              
2366 4           git_check_error(rc);
2367              
2368             OUTPUT: RETVAL
2369              
2370             void
2371             features(class)
2372             SV *class
2373              
2374             PREINIT:
2375 3 50         int ctx = GIMME_V;
2376              
2377             PPCODE:
2378 3 100         if (ctx != G_VOID) {
2379 2 100         if (ctx == G_ARRAY) {
2380 1           int features = git_libgit2_features();
2381              
2382 1 50         mXPUSHs(newSVpv("threads", 0));
2383 1 50         mXPUSHs(newSViv((features & GIT_FEATURE_THREADS) ? 1 : 0));
2384 1 50         mXPUSHs(newSVpv("https", 0));
2385 1 50         mXPUSHs(newSViv((features & GIT_FEATURE_HTTPS) ? 1 : 0));
2386 1 50         mXPUSHs(newSVpv("ssh", 0));
2387 1 50         mXPUSHs(newSViv((features & GIT_FEATURE_SSH) ? 1 : 0));
2388              
2389 1           XSRETURN(6);
2390             } else {
2391 1 50         mXPUSHs(newSViv(3));
2392 1           XSRETURN(1);
2393             }
2394             } else
2395 1           XSRETURN_EMPTY;
2396              
2397             INCLUDE: xs/AnnotatedCommit.xs
2398             INCLUDE: xs/Blame.xs
2399             INCLUDE: xs/Blame/Hunk.xs
2400             INCLUDE: xs/Blob.xs
2401             INCLUDE: xs/Branch.xs
2402             INCLUDE: xs/Cert.xs
2403             INCLUDE: xs/Cert/HostKey.xs
2404             INCLUDE: xs/Cert/X509.xs
2405             INCLUDE: xs/Commit.xs
2406             INCLUDE: xs/Config.xs
2407             INCLUDE: xs/Cred.xs
2408             INCLUDE: xs/Diff.xs
2409             INCLUDE: xs/Diff/Delta.xs
2410             INCLUDE: xs/Diff/File.xs
2411             INCLUDE: xs/Diff/Hunk.xs
2412             INCLUDE: xs/Diff/Stats.xs
2413             INCLUDE: xs/Error.xs
2414             INCLUDE: xs/Error/Category.xs
2415             INCLUDE: xs/Filter.xs
2416             INCLUDE: xs/Filter/List.xs
2417             INCLUDE: xs/Filter/Source.xs
2418             INCLUDE: xs/Graph.xs
2419             INCLUDE: xs/Index.xs
2420             INCLUDE: xs/Index/Conflict.xs
2421             INCLUDE: xs/Index/Entry.xs
2422             INCLUDE: xs/Indexer.xs
2423             INCLUDE: xs/Mempack.xs
2424             INCLUDE: xs/Merge/File/Result.xs
2425             INCLUDE: xs/Note.xs
2426             INCLUDE: xs/Object.xs
2427             INCLUDE: xs/Odb.xs
2428             INCLUDE: xs/Odb/Backend.xs
2429             INCLUDE: xs/Odb/Object.xs
2430             INCLUDE: xs/Odb/Backend/Loose.xs
2431             INCLUDE: xs/Odb/Backend/OnePack.xs
2432             INCLUDE: xs/Odb/Backend/Pack.xs
2433             INCLUDE: xs/Packbuilder.xs
2434             INCLUDE: xs/Patch.xs
2435             INCLUDE: xs/PathSpec.xs
2436             INCLUDE: xs/PathSpec/MatchList.xs
2437             INCLUDE: xs/Rebase.xs
2438             INCLUDE: xs/Rebase/Operation.xs
2439             INCLUDE: xs/Reference.xs
2440             INCLUDE: xs/Reflog.xs
2441             INCLUDE: xs/Reflog/Entry.xs
2442             INCLUDE: xs/RefSpec.xs
2443             INCLUDE: xs/Remote.xs
2444             INCLUDE: xs/Repository.xs
2445             INCLUDE: xs/Signature.xs
2446             INCLUDE: xs/Stash.xs
2447             INCLUDE: xs/Stash/Progress.xs
2448             INCLUDE: xs/Submodule.xs
2449             INCLUDE: xs/Tag.xs
2450             INCLUDE: xs/Test.xs
2451             INCLUDE: xs/TransferProgress.xs
2452             INCLUDE: xs/Tree.xs
2453             INCLUDE: xs/Tree/Builder.xs
2454             INCLUDE: xs/Tree/Entry.xs
2455             INCLUDE: xs/Walker.xs
2456             INCLUDE: xs/Worktree.xs