]>
Commit | Line | Data |
---|---|---|
18b00406 ET |
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 | ||
18b00406 | 8 | #include "annotated_commit.h" |
eae0bfdc | 9 | |
3f2bb387 | 10 | #include "refs.h" |
7730fe8e | 11 | #include "cache.h" |
18b00406 ET |
12 | |
13 | #include "git2/commit.h" | |
14 | #include "git2/refs.h" | |
15 | #include "git2/repository.h" | |
16 | #include "git2/annotated_commit.h" | |
62dd4d71 | 17 | #include "git2/revparse.h" |
76ade3a0 ET |
18 | #include "git2/tree.h" |
19 | #include "git2/index.h" | |
18b00406 ET |
20 | |
21 | static int annotated_commit_init( | |
d5592378 ET |
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)); | |
ac3d33df | 34 | GIT_ERROR_CHECK_ALLOC(annotated_commit); |
d5592378 ET |
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); | |
ac3d33df | 48 | GIT_ERROR_CHECK_ALLOC(annotated_commit->description); |
d5592378 ET |
49 | |
50 | done: | |
51 | if (!error) | |
52 | *out = annotated_commit; | |
53 | ||
54 | return error; | |
55 | } | |
56 | ||
57 | static int annotated_commit_init_from_id( | |
18b00406 ET |
58 | git_annotated_commit **out, |
59 | git_repository *repo, | |
60 | const git_oid *id, | |
d5592378 | 61 | const char *description) |
18b00406 | 62 | { |
7730fe8e | 63 | git_commit *commit = NULL; |
18b00406 ET |
64 | int error = 0; |
65 | ||
d5592378 | 66 | assert(out && repo && id); |
18b00406 ET |
67 | |
68 | *out = NULL; | |
69 | ||
d5592378 | 70 | if ((error = git_commit_lookup(&commit, repo, id)) < 0) |
7730fe8e | 71 | goto done; |
18b00406 | 72 | |
d5592378 ET |
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 | } | |
18b00406 | 94 | |
d5592378 ET |
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 | ||
ac3d33df | 108 | if ((error = git_object_peel(&commit, obj, GIT_OBJECT_COMMIT))) { |
d5592378 ET |
109 | git_object_free(obj); |
110 | return error; | |
18b00406 ET |
111 | } |
112 | ||
d5592378 ET |
113 | error = annotated_commit_init(out, (git_commit *)commit, revspec); |
114 | ||
115 | git_object_free(obj); | |
116 | git_object_free(commit); | |
7730fe8e | 117 | |
18b00406 ET |
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 | { | |
ac3d33df | 126 | git_object *peeled; |
18b00406 ET |
127 | int error = 0; |
128 | ||
129 | assert(out && repo && ref); | |
130 | ||
131 | *out = NULL; | |
132 | ||
ac3d33df | 133 | if ((error = git_reference_peel(&peeled, ref, GIT_OBJECT_COMMIT)) < 0) |
18b00406 | 134 | return error; |
ac3d33df | 135 | |
d5592378 ET |
136 | error = annotated_commit_init_from_id(out, |
137 | repo, | |
ac3d33df | 138 | git_object_id(peeled), |
d5592378 ET |
139 | git_reference_name(ref)); |
140 | ||
141 | if (!error) { | |
142 | (*out)->ref_name = git__strdup(git_reference_name(ref)); | |
ac3d33df | 143 | GIT_ERROR_CHECK_ALLOC((*out)->ref_name); |
d5592378 | 144 | } |
18b00406 | 145 | |
ac3d33df | 146 | git_object_free(peeled); |
18b00406 ET |
147 | return error; |
148 | } | |
149 | ||
3f2bb387 ET |
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 | ||
18b00406 ET |
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 | ||
d5592378 ET |
179 | if (annotated_commit_init_from_id(out, repo, id, branch_name) < 0) |
180 | return -1; | |
62dd4d71 | 181 | |
d5592378 | 182 | (*out)->ref_name = git__strdup(branch_name); |
ac3d33df | 183 | GIT_ERROR_CHECK_ALLOC((*out)->ref_name); |
62dd4d71 | 184 | |
d5592378 | 185 | (*out)->remote_url = git__strdup(remote_url); |
ac3d33df | 186 | GIT_ERROR_CHECK_ALLOC((*out)->remote_url); |
62dd4d71 | 187 | |
d5592378 | 188 | return 0; |
62dd4d71 CMN |
189 | } |
190 | ||
191 | ||
18b00406 ET |
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 | ||
ac3d33df JK |
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 | ||
18b00406 ET |
206 | void git_annotated_commit_free(git_annotated_commit *annotated_commit) |
207 | { | |
208 | if (annotated_commit == NULL) | |
209 | return; | |
210 | ||
76ade3a0 ET |
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); | |
d5592378 ET |
215 | git__free((char *)annotated_commit->description); |
216 | git__free((char *)annotated_commit->ref_name); | |
217 | git__free((char *)annotated_commit->remote_url); | |
76ade3a0 ET |
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 | } | |
18b00406 ET |
226 | |
227 | git__free(annotated_commit); | |
228 | } |