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
;
30 GIT_ASSERT_ARG(commit
);
34 annotated_commit
= git__calloc(1, sizeof(git_annotated_commit
));
35 GIT_ERROR_CHECK_ALLOC(annotated_commit
);
37 annotated_commit
->type
= GIT_ANNOTATED_COMMIT_REAL
;
39 if ((error
= git_commit_dup(&annotated_commit
->commit
, commit
)) < 0)
42 git_oid_fmt(annotated_commit
->id_str
, git_commit_id(commit
));
43 annotated_commit
->id_str
[GIT_OID_HEXSZ
] = '\0';
46 description
= annotated_commit
->id_str
;
48 annotated_commit
->description
= git__strdup(description
);
49 GIT_ERROR_CHECK_ALLOC(annotated_commit
->description
);
53 *out
= annotated_commit
;
58 static int annotated_commit_init_from_id(
59 git_annotated_commit
**out
,
62 const char *description
)
64 git_commit
*commit
= NULL
;
73 if ((error
= git_commit_lookup(&commit
, repo
, id
)) < 0)
76 error
= annotated_commit_init(out
, commit
, description
);
79 git_commit_free(commit
);
83 int git_annotated_commit_lookup(
84 git_annotated_commit
**out
,
88 return annotated_commit_init_from_id(out
, repo
, id
, NULL
);
91 int git_annotated_commit_from_commit(
92 git_annotated_commit
**out
,
95 return annotated_commit_init(out
, commit
, NULL
);
98 int git_annotated_commit_from_revspec(
99 git_annotated_commit
**out
,
100 git_repository
*repo
,
103 git_object
*obj
, *commit
;
107 GIT_ASSERT_ARG(repo
);
108 GIT_ASSERT_ARG(revspec
);
110 if ((error
= git_revparse_single(&obj
, repo
, revspec
)) < 0)
113 if ((error
= git_object_peel(&commit
, obj
, GIT_OBJECT_COMMIT
))) {
114 git_object_free(obj
);
118 error
= annotated_commit_init(out
, (git_commit
*)commit
, revspec
);
120 git_object_free(obj
);
121 git_object_free(commit
);
126 int git_annotated_commit_from_ref(
127 git_annotated_commit
**out
,
128 git_repository
*repo
,
129 const git_reference
*ref
)
135 GIT_ASSERT_ARG(repo
);
140 if ((error
= git_reference_peel(&peeled
, ref
, GIT_OBJECT_COMMIT
)) < 0)
143 error
= annotated_commit_init_from_id(out
,
145 git_object_id(peeled
),
146 git_reference_name(ref
));
149 (*out
)->ref_name
= git__strdup(git_reference_name(ref
));
150 GIT_ERROR_CHECK_ALLOC((*out
)->ref_name
);
153 git_object_free(peeled
);
157 int git_annotated_commit_from_head(
158 git_annotated_commit
**out
,
159 git_repository
*repo
)
165 GIT_ASSERT_ARG(repo
);
169 if ((error
= git_reference_lookup(&head
, repo
, GIT_HEAD_FILE
)) < 0)
172 error
= git_annotated_commit_from_ref(out
, repo
, head
);
174 git_reference_free(head
);
178 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
,
186 GIT_ASSERT_ARG(repo
);
187 GIT_ASSERT_ARG(branch_name
);
188 GIT_ASSERT_ARG(remote_url
);
191 if (annotated_commit_init_from_id(out
, repo
, id
, branch_name
) < 0)
194 (*out
)->ref_name
= git__strdup(branch_name
);
195 GIT_ERROR_CHECK_ALLOC((*out
)->ref_name
);
197 (*out
)->remote_url
= git__strdup(remote_url
);
198 GIT_ERROR_CHECK_ALLOC((*out
)->remote_url
);
204 const git_oid
*git_annotated_commit_id(
205 const git_annotated_commit
*annotated_commit
)
207 GIT_ASSERT_ARG_WITH_RETVAL(annotated_commit
, NULL
);
208 return git_commit_id(annotated_commit
->commit
);
211 const char *git_annotated_commit_ref(
212 const git_annotated_commit
*annotated_commit
)
214 GIT_ASSERT_ARG_WITH_RETVAL(annotated_commit
, NULL
);
215 return annotated_commit
->ref_name
;
218 void git_annotated_commit_free(git_annotated_commit
*annotated_commit
)
220 if (annotated_commit
== NULL
)
223 switch (annotated_commit
->type
) {
224 case GIT_ANNOTATED_COMMIT_REAL
:
225 git_commit_free(annotated_commit
->commit
);
226 git_tree_free(annotated_commit
->tree
);
227 git__free((char *)annotated_commit
->description
);
228 git__free((char *)annotated_commit
->ref_name
);
229 git__free((char *)annotated_commit
->remote_url
);
231 case GIT_ANNOTATED_COMMIT_VIRTUAL
:
232 git_index_free(annotated_commit
->index
);
233 git_array_clear(annotated_commit
->parents
);
239 git__free(annotated_commit
);