2 * Copyright (C) the libgit2 contributors. All rights reserved.
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.
8 #include "annotated_commit.h"
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"
21 static int annotated_commit_init(
22 git_annotated_commit
**out
,
24 const char *description
)
26 git_annotated_commit
*annotated_commit
;
29 assert(out
&& commit
);
33 annotated_commit
= git__calloc(1, sizeof(git_annotated_commit
));
34 GIT_ERROR_CHECK_ALLOC(annotated_commit
);
36 annotated_commit
->type
= GIT_ANNOTATED_COMMIT_REAL
;
38 if ((error
= git_commit_dup(&annotated_commit
->commit
, commit
)) < 0)
41 git_oid_fmt(annotated_commit
->id_str
, git_commit_id(commit
));
42 annotated_commit
->id_str
[GIT_OID_HEXSZ
] = '\0';
45 description
= annotated_commit
->id_str
;
47 annotated_commit
->description
= git__strdup(description
);
48 GIT_ERROR_CHECK_ALLOC(annotated_commit
->description
);
52 *out
= annotated_commit
;
57 static int annotated_commit_init_from_id(
58 git_annotated_commit
**out
,
61 const char *description
)
63 git_commit
*commit
= NULL
;
66 assert(out
&& repo
&& id
);
70 if ((error
= git_commit_lookup(&commit
, repo
, id
)) < 0)
73 error
= annotated_commit_init(out
, commit
, description
);
76 git_commit_free(commit
);
80 int git_annotated_commit_lookup(
81 git_annotated_commit
**out
,
85 return annotated_commit_init_from_id(out
, repo
, id
, NULL
);
88 int git_annotated_commit_from_commit(
89 git_annotated_commit
**out
,
92 return annotated_commit_init(out
, commit
, NULL
);
95 int git_annotated_commit_from_revspec(
96 git_annotated_commit
**out
,
100 git_object
*obj
, *commit
;
103 assert(out
&& repo
&& revspec
);
105 if ((error
= git_revparse_single(&obj
, repo
, revspec
)) < 0)
108 if ((error
= git_object_peel(&commit
, obj
, GIT_OBJECT_COMMIT
))) {
109 git_object_free(obj
);
113 error
= annotated_commit_init(out
, (git_commit
*)commit
, revspec
);
115 git_object_free(obj
);
116 git_object_free(commit
);
121 int git_annotated_commit_from_ref(
122 git_annotated_commit
**out
,
123 git_repository
*repo
,
124 const git_reference
*ref
)
129 assert(out
&& repo
&& ref
);
133 if ((error
= git_reference_peel(&peeled
, ref
, GIT_OBJECT_COMMIT
)) < 0)
136 error
= annotated_commit_init_from_id(out
,
138 git_object_id(peeled
),
139 git_reference_name(ref
));
142 (*out
)->ref_name
= git__strdup(git_reference_name(ref
));
143 GIT_ERROR_CHECK_ALLOC((*out
)->ref_name
);
146 git_object_free(peeled
);
150 int git_annotated_commit_from_head(
151 git_annotated_commit
**out
,
152 git_repository
*repo
)
161 if ((error
= git_reference_lookup(&head
, repo
, GIT_HEAD_FILE
)) < 0)
164 error
= git_annotated_commit_from_ref(out
, repo
, head
);
166 git_reference_free(head
);
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
,
177 assert(repo
&& id
&& branch_name
&& remote_url
);
179 if (annotated_commit_init_from_id(out
, repo
, id
, branch_name
) < 0)
182 (*out
)->ref_name
= git__strdup(branch_name
);
183 GIT_ERROR_CHECK_ALLOC((*out
)->ref_name
);
185 (*out
)->remote_url
= git__strdup(remote_url
);
186 GIT_ERROR_CHECK_ALLOC((*out
)->remote_url
);
192 const git_oid
*git_annotated_commit_id(
193 const git_annotated_commit
*annotated_commit
)
195 assert(annotated_commit
);
196 return git_commit_id(annotated_commit
->commit
);
199 const char *git_annotated_commit_ref(
200 const git_annotated_commit
*annotated_commit
)
202 assert(annotated_commit
);
203 return annotated_commit
->ref_name
;
206 void git_annotated_commit_free(git_annotated_commit
*annotated_commit
)
208 if (annotated_commit
== NULL
)
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
);
219 case GIT_ANNOTATED_COMMIT_VIRTUAL
:
220 git_index_free(annotated_commit
->index
);
221 git_array_clear(annotated_commit
->parents
);
227 git__free(annotated_commit
);