use std::borrow::Cow; use smallvec::SmallVec; use crate::{immutable::object, BStr}; mod decode; /// pub mod iter; /// A git commit parsed using [`from_bytes()`][Commit::from_bytes()]. /// /// A commit encapsulates information about a point in time at which the state of the repository is recorded, usually after a /// change which is documented in the commit `message`. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] pub struct Commit<'a> { /// HEX hash of tree object we point to. Usually 40 bytes long. /// /// Use [`tree()`][Commit::tree()] to obtain a decoded version of it. #[cfg_attr(feature = "serde1", serde(borrow))] pub tree: &'a BStr, /// HEX hash of each parent commit. Empty for first commit in repository. pub parents: SmallVec<[&'a BStr; 2]>, /// Who wrote this commit. pub author: git_actor::immutable::Signature<'a>, /// Who committed this commit. /// /// This may be different from the `author` in case the author couldn't write to the repository themselves and /// is commonly encountered with contributed commits. pub committer: git_actor::immutable::Signature<'a>, /// The name of the message encoding, otherwise [UTF-8 should be assumed](https://github.com/git/git/blob/e67fbf927dfdf13d0b21dc6ea15dc3c7ef448ea0/commit.c#L1493:L1493). pub encoding: Option<&'a BStr>, /// The commit message documenting the change. pub message: &'a BStr, /// Extra header fields, in order of them being encountered, made accessible with the iterator returned by [`extra_headers()`][Commit::extra_headers()]. pub extra_headers: Vec<(&'a BStr, Cow<'a, BStr>)>, } impl<'a> Commit<'a> { /// Deserialize a commit from the given `data` bytes while avoiding most allocations. pub fn from_bytes(data: &'a [u8]) -> Result, object::decode::Error> { decode::commit(data) .map(|(_, t)| t) .map_err(object::decode::Error::from) } /// Return the `tree` fields hash digest. pub fn tree(&self) -> git_hash::ObjectId { git_hash::ObjectId::from_hex(self.tree).expect("prior validation of tree hash during parsing") } /// Returns an iterator of parent object ids pub fn parents(&self) -> impl Iterator + '_ { self.parents .iter() .map(|hex_hash| git_hash::ObjectId::from_hex(hex_hash).expect("prior validation of hashes during parsing")) } /// Returns a convenient iterator over all extra headers. pub fn extra_headers(&self) -> crate::commit::ExtraHeaders> { crate::commit::ExtraHeaders::new(self.extra_headers.iter().map(|(k, v)| (*k, v.as_ref()))) } }