GCC Code Coverage Report


Directory: src/
File: src/git.c
Date: 2026-09-21 17:23:28
Exec Total Coverage
Lines: 39 55 70.9%
Functions: 6 6 100.0%
Branches: 10 64 15.6%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2022 Egor Tensin <egor@tensin.name>
3 * This file is part of the "cimple" project.
4 * For details, see https://github.com/egor-tensin/cimple
5 * Distributed under the MIT License.
6 */
7
8 #include "git.h"
9
10 #include "log.h"
11
12 #include <git2.h>
13
14 #include <stdlib.h>
15
16 #define git_log_err(fn) \
17 do { \
18 const git_error* error = git_error_last(); \
19 const char* msg = error && error->message ? error->message : "???"; \
20 log_err("%s: %s\n", fn, msg); \
21 } while (0)
22
23 54 int libgit_init(void) {
24 54 int ret = 0;
25
26 54 ret = git_libgit2_init();
27
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (ret < 0) {
28 git_log_err("git_libgit2_init");
29 return ret;
30 }
31
32 54 return 0;
33 }
34
35 54 void libgit_shutdown(void) {
36 54 git_libgit2_shutdown();
37 54 }
38
39 9180 int libgit_clone(git_repository** repo, const char* url, const char* dir) {
40 git_clone_options opts;
41 9180 int ret = 0;
42
43
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9180 times.
9180 log("Cloning git repository from %s to %s\n", url, dir);
44
45 9180 ret = git_clone_options_init(&opts, GIT_CLONE_OPTIONS_VERSION);
46
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9180 times.
9180 if (ret < 0) {
47 git_log_err("git_clone_options_init");
48 return ret;
49 }
50 9180 opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
51
52 9180 ret = git_clone(repo, url, dir, &opts);
53
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9180 times.
9180 if (ret < 0) {
54 git_log_err("git_clone");
55 return ret;
56 }
57
58 9180 return 0;
59 }
60
61 9180 int libgit_clone_to_tmp(git_repository** repo, const char* url) {
62 9180 char dir[] = "/tmp/git.XXXXXX";
63
64
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9180 times.
9180 if (!mkdtemp(dir)) {
65 log_errno("mkdtemp");
66 return -1;
67 }
68
69 9180 return libgit_clone(repo, url, dir);
70 }
71
72 9180 void libgit_repository_free(git_repository* repo) {
73 9180 git_repository_free(repo);
74 9180 }
75
76 9180 int libgit_checkout(git_repository* repo, const char* rev) {
77 git_checkout_options opts;
78 git_object* obj;
79 9180 int ret = 0;
80
81
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9180 times.
9180 log("Checking out revision %s\n", rev);
82
83 9180 ret = git_revparse_single(&obj, repo, rev);
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9180 times.
9180 if (ret < 0) {
85 git_log_err("git_revparse_single");
86 return ret;
87 }
88
89 9180 ret = git_checkout_options_init(&opts, GIT_CHECKOUT_OPTIONS_VERSION);
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9180 times.
9180 if (ret < 0) {
91 git_log_err("git_checkout_options_init");
92 goto free_obj;
93 }
94 9180 opts.checkout_strategy = GIT_CHECKOUT_FORCE;
95
96 9180 ret = git_checkout_tree(repo, obj, &opts);
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9180 times.
9180 if (ret < 0) {
98 git_log_err("git_checkout_tree");
99 goto free_obj;
100 }
101
102 9180 ret = git_repository_set_head_detached(repo, git_object_id(obj));
103
1/2
✓ Branch 0 taken 9180 times.
✗ Branch 1 not taken.
9180 if (ret < 0) {
104 git_log_err("git_repository_set_head_detached");
105 goto free_obj;
106 }
107
108 9180 free_obj:
109 9180 git_object_free(obj);
110
111 9180 return ret;
112 }
113