Use gitoxide in get_commit_info (#2654)

* Implement From<gix::ObjectId> for CommitId

* Use gitoxide in get_commit_info
This commit is contained in:
Christoph Rüßler 2025-05-26 23:06:36 +02:00 committed by GitHub
parent 7625277953
commit 2d7d1730ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 78 additions and 13 deletions

13
Cargo.lock generated
View file

@ -1224,6 +1224,7 @@ dependencies = [
"gix-hashtable",
"gix-index",
"gix-lock",
"gix-mailmap",
"gix-object",
"gix-odb",
"gix-pack",
@ -1486,6 +1487,18 @@ dependencies = [
"thiserror 2.0.12",
]
[[package]]
name = "gix-mailmap"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff80d086d2684d30c5785cc37eba9d2cf817cfb33797ed999db9a359d16ab393"
dependencies = [
"bstr",
"gix-actor",
"gix-date",
"thiserror 2.0.12",
]
[[package]]
name = "gix-object"
version = "0.48.0"

View file

@ -27,6 +27,7 @@ git2-hooks = { path = "../git2-hooks", version = ">=0.4" }
gix = { version = "0.71.0", default-features = false, features = [
"max-performance",
"revision",
"mailmap"
] }
log = "0.4"
# git2 = { path = "../../extern/git2-rs", features = ["vendored-openssl"]}

View file

@ -113,6 +113,16 @@ pub enum Error {
#[error("gix::revision::walk error: {0}")]
GixRevisionWalk(#[from] gix::revision::walk::Error),
///
#[error("gix::objs::decode::Error error: {0}")]
GixObjsDecode(#[from] gix::objs::decode::Error),
///
#[error("gix::object::find::existing::with_conversion::Error error: {0}")]
GixObjectFindExistingWithConversionError(
#[from] gix::object::find::existing::with_conversion::Error,
),
///
#[error("amend error: config commit.gpgsign=true detected.\ngpg signing is not supported for amending non-last commits")]
SignAmendNonLastCommit,

View file

@ -84,6 +84,21 @@ impl From<Oid> for CommitId {
}
}
impl From<gix::ObjectId> for CommitId {
fn from(object_id: gix::ObjectId) -> Self {
#[allow(clippy::expect_used)]
let oid = Oid::from_bytes(object_id.as_bytes()).expect("`Oid::from_bytes(object_id.as_bytes())` is expected to never fail");
Self::new(oid)
}
}
impl From<CommitId> for gix::ObjectId {
fn from(id: CommitId) -> Self {
Self::from_bytes_or_panic(id.0.as_bytes())
}
}
///
#[derive(Debug, Clone)]
pub struct CommitInfo {
@ -142,24 +157,35 @@ pub fn get_commit_info(
) -> Result<CommitInfo> {
scope_time!("get_commit_info");
let repo = repo(repo_path)?;
let mailmap = repo.mailmap()?;
let repo: gix::Repository =
gix::ThreadSafeRepository::discover_with_environment_overrides(repo_path.gitpath())
.map(Into::into)?;
let mailmap = repo.open_mailmap();
let commit = repo.find_commit((*commit_id).into())?;
let author = get_author_of_commit(&commit, &mailmap);
let commit = repo.find_commit(*commit_id)?;
let commit_ref = commit.decode()?;
let message = gix_get_message(&commit_ref, None);
let author = commit_ref.author();
let author = mailmap.try_resolve(author).map_or_else(
|| author.name.into(),
|signature| signature.name,
);
Ok(CommitInfo {
message: commit.message().unwrap_or("").into(),
author: author.name().unwrap_or("<unknown>").into(),
time: commit.time().seconds(),
id: CommitId(commit.id()),
message,
author: author.to_string(),
time: commit_ref.time().seconds,
id: commit.id().detach().into(),
})
}
/// if `message_limit` is set the message will be
/// limited to the first line and truncated to fit
pub fn get_message(
c: &Commit,
c: &git2::Commit,
message_limit: Option<usize>,
) -> String {
let msg = String::from_utf8_lossy(c.message_bytes());
@ -174,6 +200,24 @@ pub fn get_message(
)
}
/// if `message_limit` is set the message will be
/// limited to the first line and truncated to fit
pub fn gix_get_message(
commit_ref: &gix::objs::CommitRef,
message_limit: Option<usize>,
) -> String {
let message = commit_ref.message.to_string();
let message = message.trim();
message_limit.map_or_else(
|| message.to_string(),
|limit| {
let message = message.lines().next().unwrap_or_default();
message.unicode_truncate(limit).0.to_string()
},
)
}
#[cfg(test)]
mod tests {
use super::get_commits_info;

View file

@ -161,10 +161,7 @@ impl<'a> LogWalkerWithoutFilter<'a> {
let mut count = 0_usize;
while let Some(Ok(info)) = self.walk.next() {
let bytes = info.id.as_bytes();
let commit_id: CommitId = Oid::from_bytes(bytes)?.into();
out.push(commit_id);
out.push(info.id.into());
count += 1;