File Coverage

deps/libgit2/src/libgit2/annotated_commit.c
Criterion Covered Total %
statement 69 105 65.7
branch 25 72 34.7
condition n/a
subroutine n/a
pod n/a
total 94 177 53.1


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
4             * This file is part of libgit2, distributed under the GNU GPL v2 with
5             * a Linking Exception. For full terms see the included COPYING file.
6             */
7              
8             #include "annotated_commit.h"
9              
10             #include "refs.h"
11             #include "cache.h"
12              
13             #include "git2/commit.h"
14             #include "git2/refs.h"
15             #include "git2/repository.h"
16             #include "git2/annotated_commit.h"
17             #include "git2/revparse.h"
18             #include "git2/tree.h"
19             #include "git2/index.h"
20              
21 48           static int annotated_commit_init(
22             git_annotated_commit **out,
23             git_commit *commit,
24             const char *description)
25             {
26             git_annotated_commit *annotated_commit;
27 48           int error = 0;
28              
29 48 50         GIT_ASSERT_ARG(out);
30 48 50         GIT_ASSERT_ARG(commit);
31              
32 48           *out = NULL;
33              
34 48           annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
35 48 50         GIT_ERROR_CHECK_ALLOC(annotated_commit);
36              
37 48           annotated_commit->type = GIT_ANNOTATED_COMMIT_REAL;
38              
39 48 50         if ((error = git_commit_dup(&annotated_commit->commit, commit)) < 0)
40 0           goto done;
41              
42 48           git_oid_fmt(annotated_commit->id_str, git_commit_id(commit));
43 48           annotated_commit->id_str[GIT_OID_HEXSZ] = '\0';
44              
45 48 100         if (!description)
46 22           description = annotated_commit->id_str;
47              
48 48           annotated_commit->description = git__strdup(description);
49 48 50         GIT_ERROR_CHECK_ALLOC(annotated_commit->description);
50              
51             done:
52 48 50         if (!error)
53 48           *out = annotated_commit;
54              
55 48           return error;
56             }
57              
58 47           static int annotated_commit_init_from_id(
59             git_annotated_commit **out,
60             git_repository *repo,
61             const git_oid *id,
62             const char *description)
63             {
64 47           git_commit *commit = NULL;
65 47           int error = 0;
66              
67 47 50         GIT_ASSERT_ARG(out);
68 47 50         GIT_ASSERT_ARG(repo);
69 47 50         GIT_ASSERT_ARG(id);
70              
71 47           *out = NULL;
72              
73 47 100         if ((error = git_commit_lookup(&commit, repo, id)) < 0)
74 1           goto done;
75              
76 46           error = annotated_commit_init(out, commit, description);
77              
78             done:
79 47           git_commit_free(commit);
80 47           return error;
81             }
82              
83 21           int git_annotated_commit_lookup(
84             git_annotated_commit **out,
85             git_repository *repo,
86             const git_oid *id)
87             {
88 21           return annotated_commit_init_from_id(out, repo, id, NULL);
89             }
90              
91 2           int git_annotated_commit_from_commit(
92             git_annotated_commit **out,
93             git_commit *commit)
94             {
95 2           return annotated_commit_init(out, commit, NULL);
96             }
97              
98 0           int git_annotated_commit_from_revspec(
99             git_annotated_commit **out,
100             git_repository *repo,
101             const char *revspec)
102             {
103             git_object *obj, *commit;
104             int error;
105              
106 0 0         GIT_ASSERT_ARG(out);
107 0 0         GIT_ASSERT_ARG(repo);
108 0 0         GIT_ASSERT_ARG(revspec);
109              
110 0 0         if ((error = git_revparse_single(&obj, repo, revspec)) < 0)
111 0           return error;
112              
113 0 0         if ((error = git_object_peel(&commit, obj, GIT_OBJECT_COMMIT))) {
114 0           git_object_free(obj);
115 0           return error;
116             }
117              
118 0           error = annotated_commit_init(out, (git_commit *)commit, revspec);
119              
120 0           git_object_free(obj);
121 0           git_object_free(commit);
122              
123 0           return error;
124             }
125              
126 26           int git_annotated_commit_from_ref(
127             git_annotated_commit **out,
128             git_repository *repo,
129             const git_reference *ref)
130             {
131             git_object *peeled;
132 26           int error = 0;
133              
134 26 50         GIT_ASSERT_ARG(out);
135 26 50         GIT_ASSERT_ARG(repo);
136 26 50         GIT_ASSERT_ARG(ref);
137              
138 26           *out = NULL;
139              
140 26 50         if ((error = git_reference_peel(&peeled, ref, GIT_OBJECT_COMMIT)) < 0)
141 0           return error;
142              
143 26           error = annotated_commit_init_from_id(out,
144             repo,
145             git_object_id(peeled),
146             git_reference_name(ref));
147              
148 26 50         if (!error) {
149 26           (*out)->ref_name = git__strdup(git_reference_name(ref));
150 26 50         GIT_ERROR_CHECK_ALLOC((*out)->ref_name);
151             }
152              
153 26           git_object_free(peeled);
154 26           return error;
155             }
156              
157 5           int git_annotated_commit_from_head(
158             git_annotated_commit **out,
159             git_repository *repo)
160             {
161             git_reference *head;
162             int error;
163              
164 5 50         GIT_ASSERT_ARG(out);
165 5 50         GIT_ASSERT_ARG(repo);
166              
167 5           *out = NULL;
168              
169 5 50         if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
170 0           return -1;
171              
172 5           error = git_annotated_commit_from_ref(out, repo, head);
173              
174 5           git_reference_free(head);
175 5           return error;
176             }
177              
178 0           int git_annotated_commit_from_fetchhead(
179             git_annotated_commit **out,
180             git_repository *repo,
181             const char *branch_name,
182             const char *remote_url,
183             const git_oid *id)
184             {
185 0 0         GIT_ASSERT_ARG(out);
186 0 0         GIT_ASSERT_ARG(repo);
187 0 0         GIT_ASSERT_ARG(branch_name);
188 0 0         GIT_ASSERT_ARG(remote_url);
189 0 0         GIT_ASSERT_ARG(id);
190              
191 0 0         if (annotated_commit_init_from_id(out, repo, id, branch_name) < 0)
192 0           return -1;
193              
194 0           (*out)->ref_name = git__strdup(branch_name);
195 0 0         GIT_ERROR_CHECK_ALLOC((*out)->ref_name);
196              
197 0           (*out)->remote_url = git__strdup(remote_url);
198 0 0         GIT_ERROR_CHECK_ALLOC((*out)->remote_url);
199              
200 0           return 0;
201             }
202              
203              
204 52           const git_oid *git_annotated_commit_id(
205             const git_annotated_commit *annotated_commit)
206             {
207 52 50         GIT_ASSERT_ARG_WITH_RETVAL(annotated_commit, NULL);
208 52           return git_commit_id(annotated_commit->commit);
209             }
210              
211 0           const char *git_annotated_commit_ref(
212             const git_annotated_commit *annotated_commit)
213             {
214 0 0         GIT_ASSERT_ARG_WITH_RETVAL(annotated_commit, NULL);
215 0           return annotated_commit->ref_name;
216             }
217              
218 66           void git_annotated_commit_free(git_annotated_commit *annotated_commit)
219             {
220 66 100         if (annotated_commit == NULL)
221 21           return;
222              
223 45           switch (annotated_commit->type) {
224             case GIT_ANNOTATED_COMMIT_REAL:
225 45           git_commit_free(annotated_commit->commit);
226 45           git_tree_free(annotated_commit->tree);
227 45           git__free((char *)annotated_commit->description);
228 45           git__free((char *)annotated_commit->ref_name);
229 45           git__free((char *)annotated_commit->remote_url);
230 45           break;
231             case GIT_ANNOTATED_COMMIT_VIRTUAL:
232 0           git_index_free(annotated_commit->index);
233 0           git_array_clear(annotated_commit->parents);
234 0           break;
235             default:
236 0           abort();
237             }
238              
239 45           git__free(annotated_commit);
240             }