Respect .mailmap (#2485)

This commit is contained in:
Lena 2025-03-19 13:44:02 +00:00 committed by GitHub
parent 3ede6b56f1
commit 92ef9f6fde
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 78 additions and 19 deletions

View file

@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* use OSC52 copying in case other methods fail [[@naseschwarz](https://github.com/naseschwarz)] ([#2366](https://github.com/gitui-org/gitui/issues/2366))
* push: respect `branch.*.merge` when push default is upstream [[@vlad-anger](https://github.com/vlad-anger)] ([#2542](https://github.com/gitui-org/gitui/pull/2542))
* set the terminal title to `gitui ({repo_path})` [[@acuteenvy](https://github.com/acuteenvy)] ([#2462](https://github.com/gitui-org/gitui/issues/2462))
* respect `.mailmap` [[@acuteenvy](https://github.com/acuteenvy)] ([#2406](https://github.com/gitui-org/gitui/issues/2406))
## [0.27.0] - 2024-01-14

View file

@ -87,6 +87,42 @@ impl CommitDetails {
}
}
/// Get the author of a commit.
pub fn get_author_of_commit<'a>(
commit: &'a git2::Commit<'a>,
mailmap: &git2::Mailmap,
) -> git2::Signature<'a> {
match commit.author_with_mailmap(mailmap) {
Ok(author) => author,
Err(e) => {
log::error!(
"Couldn't get author with mailmap for {} (message: {:?}): {e}",
commit.id(),
commit.message(),
);
commit.author()
}
}
}
/// Get the committer of a commit.
pub fn get_committer_of_commit<'a>(
commit: &'a git2::Commit<'a>,
mailmap: &git2::Mailmap,
) -> git2::Signature<'a> {
match commit.committer_with_mailmap(mailmap) {
Ok(committer) => committer,
Err(e) => {
log::error!(
"Couldn't get committer with mailmap for {} (message: {:?}): {e}",
commit.id(),
commit.message(),
);
commit.committer()
}
}
}
///
pub fn get_commit_details(
repo_path: &RepoPath,
@ -95,11 +131,17 @@ pub fn get_commit_details(
scope_time!("get_commit_details");
let repo = repo(repo_path)?;
let mailmap = repo.mailmap()?;
let commit = repo.find_commit(id.into())?;
let author = CommitSignature::from(&commit.author());
let committer = CommitSignature::from(&commit.committer());
let author = CommitSignature::from(&get_author_of_commit(
&commit, &mailmap,
));
let committer = CommitSignature::from(&get_committer_of_commit(
&commit, &mailmap,
));
let committer = if author == committer {
None
} else {

View file

@ -1,4 +1,7 @@
use super::{commit_files::get_commit_diff, CommitId};
use super::{
commit_details::get_author_of_commit,
commit_files::get_commit_diff, CommitId,
};
use crate::error::Result;
use bitflags::bitflags;
use fuzzy_matcher::FuzzyMatcher;
@ -159,6 +162,7 @@ pub fn filter_commit_by_search(
move |repo: &Repository,
commit_id: &CommitId|
-> Result<bool> {
let mailmap = repo.mailmap()?;
let commit = repo.find_commit((*commit_id).into())?;
let msg_summary_match = filter
@ -199,16 +203,15 @@ pub fn filter_commit_by_search(
.fields
.contains(SearchFields::AUTHORS)
.then(|| {
let name_match = commit
.author()
.name()
.is_some_and(|name| filter.match_text(name));
let mail_match = commit
.author()
.email()
.is_some_and(|name| filter.match_text(name));
name_match || mail_match
let author =
get_author_of_commit(&commit, &mailmap);
[author.email(), author.name()].iter().any(
|opt_haystack| {
opt_haystack.is_some_and(|haystack| {
filter.match_text(haystack)
})
},
)
})
.unwrap_or_default();

View file

@ -1,7 +1,10 @@
use std::fmt::Display;
use super::RepoPath;
use crate::{error::Result, sync::repository::repo};
use crate::{
error::Result,
sync::{commit_details::get_author_of_commit, repository::repo},
};
use git2::{Commit, Error, Oid};
use scopetime::scope_time;
use unicode_truncate::UnicodeTruncateStr;
@ -91,6 +94,7 @@ pub fn get_commits_info(
scope_time!("get_commits_info");
let repo = repo(repo_path)?;
let mailmap = repo.mailmap()?;
let commits = ids
.iter()
@ -101,10 +105,12 @@ pub fn get_commits_info(
let res = commits
.map(|c: Commit| {
let message = get_message(&c, Some(message_length_limit));
let author = c.author().name().map_or_else(
|| String::from("<unknown>"),
String::from,
);
let author = get_author_of_commit(&c, &mailmap)
.name()
.map_or_else(
|| String::from("<unknown>"),
String::from,
);
CommitInfo {
message,
author,
@ -125,9 +131,10 @@ pub fn get_commit_info(
scope_time!("get_commit_info");
let repo = repo(repo_path)?;
let mailmap = repo.mailmap()?;
let commit = repo.find_commit((*commit_id).into())?;
let author = commit.author();
let author = get_author_of_commit(&commit, &mailmap);
Ok(CommitInfo {
message: commit.message().unwrap_or("").into(),
@ -189,6 +196,12 @@ mod tests {
assert_eq!(res[0].author.as_str(), "name");
assert_eq!(res[1].message.as_str(), "commit1");
File::create(root.join(".mailmap"))?
.write_all(b"new name <newemail> <email>")?;
let res = get_commits_info(repo_path, &[c2], 50).unwrap();
assert_eq!(res[0].author.as_str(), "new name");
Ok(())
}