1use crate::{bstr, bstr::BStr, Commit, ObjectDetached, Tree};
2
3mod error {
4 use crate::object;
5
6 #[derive(Debug, thiserror::Error)]
7 #[allow(missing_docs)]
8 pub enum Error {
9 #[error(transparent)]
10 FindExistingObject(#[from] object::find::existing::Error),
11 #[error("The commit could not be decoded fully or partially")]
12 Decode(#[from] gix_object::decode::Error),
13 #[error("The commit date could not be parsed")]
14 ParseDate(#[from] gix_date::parse::Error),
15 #[error("Expected object of type {}, but got {}", .expected, .actual)]
16 ObjectKind {
17 expected: gix_object::Kind,
18 actual: gix_object::Kind,
19 },
20 }
21}
22
23pub use error::Error;
24
25impl Commit<'_> {
27 pub fn detached(&self) -> ObjectDetached {
29 ObjectDetached {
30 id: self.id,
31 kind: gix_object::Kind::Commit,
32 data: self.data.clone(),
33 }
34 }
35
36 pub fn detach(self) -> ObjectDetached {
38 self.into()
39 }
40
41 pub fn take_data(&mut self) -> Vec<u8> {
45 std::mem::take(&mut self.data)
46 }
47}
48
49impl<'repo> Commit<'repo> {
50 pub fn short_id(&self) -> Result<gix_hash::Prefix, crate::id::shorten::Error> {
52 use crate::ext::ObjectIdExt;
53 self.id.attach(self.repo).shorten()
54 }
55
56 pub fn message(&self) -> Result<gix_object::commit::MessageRef<'_>, gix_object::decode::Error> {
58 Ok(gix_object::commit::MessageRef::from_bytes(self.message_raw()?))
59 }
60 pub fn message_raw(&self) -> Result<&'_ BStr, gix_object::decode::Error> {
62 gix_object::CommitRefIter::from_bytes(&self.data).message()
63 }
64 pub fn message_raw_sloppy(&self) -> &BStr {
67 use bstr::ByteSlice;
68 self.data
69 .find(b"\n\n")
70 .map(|pos| &self.data[pos + 2..])
71 .unwrap_or_default()
72 .as_bstr()
73 }
74
75 pub fn time(&self) -> Result<gix_date::Time, Error> {
79 Ok(self.committer()?.time()?)
80 }
81
82 pub fn decode(&self) -> Result<gix_object::CommitRef<'_>, gix_object::decode::Error> {
90 gix_object::CommitRef::from_bytes(&self.data)
91 }
92
93 pub fn iter(&self) -> gix_object::CommitRefIter<'_> {
95 gix_object::CommitRefIter::from_bytes(&self.data)
96 }
97
98 pub fn author(&self) -> Result<gix_actor::SignatureRef<'_>, gix_object::decode::Error> {
100 gix_object::CommitRefIter::from_bytes(&self.data)
101 .author()
102 .map(|s| s.trim())
103 }
104
105 pub fn committer(&self) -> Result<gix_actor::SignatureRef<'_>, gix_object::decode::Error> {
107 gix_object::CommitRefIter::from_bytes(&self.data)
108 .committer()
109 .map(|s| s.trim())
110 }
111
112 pub fn parent_ids(&self) -> impl Iterator<Item = crate::Id<'repo>> + '_ {
115 use crate::ext::ObjectIdExt;
116 let repo = self.repo;
117 gix_object::CommitRefIter::from_bytes(&self.data)
118 .parent_ids()
119 .map(move |id| id.attach(repo))
120 }
121
122 pub fn tree(&self) -> Result<Tree<'repo>, Error> {
124 match self.tree_id()?.object()?.try_into_tree() {
125 Ok(tree) => Ok(tree),
126 Err(crate::object::try_into::Error { actual, expected, .. }) => Err(Error::ObjectKind { actual, expected }),
127 }
128 }
129
130 pub fn tree_id(&self) -> Result<crate::Id<'repo>, gix_object::decode::Error> {
132 gix_object::CommitRefIter::from_bytes(&self.data)
133 .tree_id()
134 .map(|id| crate::Id::from_id(id, self.repo))
135 }
136
137 pub fn id(&self) -> crate::Id<'repo> {
139 use crate::ext::ObjectIdExt;
140 self.id.attach(self.repo)
141 }
142
143 pub fn ancestors(&self) -> crate::revision::walk::Platform<'repo> {
145 self.id().ancestors()
146 }
147
148 #[cfg(feature = "revision")]
151 pub fn describe(&self) -> crate::commit::describe::Platform<'repo> {
152 crate::commit::describe::Platform {
153 id: self.id,
154 repo: self.repo,
155 select: Default::default(),
156 first_parent: false,
157 id_as_fallback: false,
158 max_candidates: 10,
159 }
160 }
161
162 pub fn signature(
165 &self,
166 ) -> Result<Option<(std::borrow::Cow<'_, BStr>, gix_object::commit::SignedData<'_>)>, gix_object::decode::Error>
167 {
168 gix_object::CommitRefIter::signature(&self.data)
169 }
170}
171
172impl std::fmt::Debug for Commit<'_> {
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 write!(f, "Commit({})", self.id)
175 }
176}