Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect .mailmap #2485

Merged
merged 10 commits into from
Mar 19, 2025
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
46 changes: 44 additions & 2 deletions asyncgit/src/sync/commit_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {
Expand Down
25 changes: 14 additions & 11 deletions asyncgit/src/sync/commit_filter.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();

Expand Down
25 changes: 19 additions & 6 deletions asyncgit/src/sync/commits_info.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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()
Expand All @@ -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,
Expand All @@ -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(),
Expand Down Expand Up @@ -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(())
}

Expand Down