]> git.proxmox.com Git - libgit2.git/blob - src/annotated_commit.c
install as examples
[libgit2.git] / src / annotated_commit.c
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 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 int error = 0;
28
29 assert(out && commit);
30
31 *out = NULL;
32
33 annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
34 GIT_ERROR_CHECK_ALLOC(annotated_commit);
35
36 annotated_commit->type = GIT_ANNOTATED_COMMIT_REAL;
37
38 if ((error = git_commit_dup(&annotated_commit->commit, commit)) < 0)
39 goto done;
40
41 git_oid_fmt(annotated_commit->id_str, git_commit_id(commit));
42 annotated_commit->id_str[GIT_OID_HEXSZ] = '\0';
43
44 if (!description)
45 description = annotated_commit->id_str;
46
47 annotated_commit->description = git__strdup(description);
48 GIT_ERROR_CHECK_ALLOC(annotated_commit->description);
49
50 done:
51 if (!error)
52 *out = annotated_commit;
53
54 return error;
55 }
56
57 static int annotated_commit_init_from_id(
58 git_annotated_commit **out,
59 git_repository *repo,
60 const git_oid *id,
61 const char *description)
62 {
63 git_commit *commit = NULL;
64 int error = 0;
65
66 assert(out && repo && id);
67
68 *out = NULL;
69
70 if ((error = git_commit_lookup(&commit, repo, id)) < 0)
71 goto done;
72
73 error = annotated_commit_init(out, commit, description);
74
75 done:
76 git_commit_free(commit);
77 return error;
78 }
79
80 int git_annotated_commit_lookup(
81 git_annotated_commit **out,
82 git_repository *repo,
83 const git_oid *id)
84 {
85 return annotated_commit_init_from_id(out, repo, id, NULL);
86 }
87
88 int git_annotated_commit_from_commit(
89 git_annotated_commit **out,
90 git_commit *commit)
91 {
92 return annotated_commit_init(out, commit, NULL);
93 }
94
95 int git_annotated_commit_from_revspec(
96 git_annotated_commit **out,
97 git_repository *repo,
98 const char *revspec)
99 {
100 git_object *obj, *commit;
101 int error;
102
103 assert(out && repo && revspec);
104
105 if ((error = git_revparse_single(&obj, repo, revspec)) < 0)
106 return error;
107
108 if ((error = git_object_peel(&commit, obj, GIT_OBJECT_COMMIT))) {
109 git_object_free(obj);
110 return error;
111 }
112
113 error = annotated_commit_init(out, (git_commit *)commit, revspec);
114
115 git_object_free(obj);
116 git_object_free(commit);
117
118 return error;
119 }
120
121 int git_annotated_commit_from_ref(
122 git_annotated_commit **out,
123 git_repository *repo,
124 const git_reference *ref)
125 {
126 git_object *peeled;
127 int error = 0;
128
129 assert(out && repo && ref);
130
131 *out = NULL;
132
133 if ((error = git_reference_peel(&peeled, ref, GIT_OBJECT_COMMIT)) < 0)
134 return error;
135
136 error = annotated_commit_init_from_id(out,
137 repo,
138 git_object_id(peeled),
139 git_reference_name(ref));
140
141 if (!error) {
142 (*out)->ref_name = git__strdup(git_reference_name(ref));
143 GIT_ERROR_CHECK_ALLOC((*out)->ref_name);
144 }
145
146 git_object_free(peeled);
147 return error;
148 }
149
150 int git_annotated_commit_from_head(
151 git_annotated_commit **out,
152 git_repository *repo)
153 {
154 git_reference *head;
155 int error;
156
157 assert(out && repo);
158
159 *out = NULL;
160
161 if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
162 return -1;
163
164 error = git_annotated_commit_from_ref(out, repo, head);
165
166 git_reference_free(head);
167 return error;
168 }
169
170 int git_annotated_commit_from_fetchhead(
171 git_annotated_commit **out,
172 git_repository *repo,
173 const char *branch_name,
174 const char *remote_url,
175 const git_oid *id)
176 {
177 assert(repo && id && branch_name && remote_url);
178
179 if (annotated_commit_init_from_id(out, repo, id, branch_name) < 0)
180 return -1;
181
182 (*out)->ref_name = git__strdup(branch_name);
183 GIT_ERROR_CHECK_ALLOC((*out)->ref_name);
184
185 (*out)->remote_url = git__strdup(remote_url);
186 GIT_ERROR_CHECK_ALLOC((*out)->remote_url);
187
188 return 0;
189 }
190
191
192 const git_oid *git_annotated_commit_id(
193 const git_annotated_commit *annotated_commit)
194 {
195 assert(annotated_commit);
196 return git_commit_id(annotated_commit->commit);
197 }
198
199 const char *git_annotated_commit_ref(
200 const git_annotated_commit *annotated_commit)
201 {
202 assert(annotated_commit);
203 return annotated_commit->ref_name;
204 }
205
206 void git_annotated_commit_free(git_annotated_commit *annotated_commit)
207 {
208 if (annotated_commit == NULL)
209 return;
210
211 switch (annotated_commit->type) {
212 case GIT_ANNOTATED_COMMIT_REAL:
213 git_commit_free(annotated_commit->commit);
214 git_tree_free(annotated_commit->tree);
215 git__free((char *)annotated_commit->description);
216 git__free((char *)annotated_commit->ref_name);
217 git__free((char *)annotated_commit->remote_url);
218 break;
219 case GIT_ANNOTATED_COMMIT_VIRTUAL:
220 git_index_free(annotated_commit->index);
221 git_array_clear(annotated_commit->parents);
222 break;
223 default:
224 abort();
225 }
226
227 git__free(annotated_commit);
228 }