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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added
* respect `.mailmap` [[@acuteenvy](https://github.com/acuteenvy)] ([#2406](https://github.com/extrawurst/gitui/issues/2406))

## [0.27.0] - 2024-01-14

**new: manage remotes**
Expand Down
36 changes: 34 additions & 2 deletions asyncgit/src/sync/commit_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,24 @@ 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(err) => {
log::error!(
"Couldn't get author with mailmap for {} {:?}: {err}",
commit.id(),
commit.message(),
);
commit.author()
}
}
}

///
pub fn get_commit_details(
repo_path: &RepoPath,
Expand All @@ -95,11 +113,25 @@ 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 = match commit.committer_with_mailmap(&mailmap) {
Ok(committer) => committer,
Err(err) => {
log::error!(
"Couldn't get committer with mailmap for {} {:?}: {err}",
commit.id(),
commit.message(),
);
commit.committer()
}
};
let committer = CommitSignature::from(&committer);
let committer = if author == committer {
None
} else {
Expand Down
26 changes: 17 additions & 9 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,14 +203,18 @@ 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));
let name_match =
get_author_of_commit(&commit, &mailmap)
.name()
.is_some_and(|name| {
filter.match_text(name)
});
let mail_match =
get_author_of_commit(&commit, &mailmap)
.email()
.is_some_and(|name| {
filter.match_text(name)
});

name_match || mail_match
})
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