optimize logfilter to not check stashes

logfilter using `get_commit_diff` on each entry lead to a lot of unneeded calls to `get_stashes` and `is_stash_commit` which should be not even needed for file history log entries. this is not happening now anymore
This commit is contained in:
extrawurst 2023-08-11 11:38:21 +02:00
parent e90656d61c
commit 9eb8d470a4
5 changed files with 35 additions and 39 deletions

View file

@ -1,14 +1,14 @@
//! Functions for getting infos about files in commits
use super::{
diff::DiffOptions, stash::is_stash_commit, CommitId, RepoPath,
};
use super::{diff::DiffOptions, CommitId, RepoPath};
use crate::{
error::Result, sync::repository::repo, StatusItem, StatusItemType,
error::Result,
sync::{get_stashes, repository::repo},
StatusItem, StatusItemType,
};
use git2::{Diff, Repository};
use scopetime::scope_time;
use std::cmp::Ordering;
use std::{cmp::Ordering, collections::HashSet};
/// get all files that are part of a commit
pub fn get_commit_files(
@ -23,7 +23,13 @@ pub fn get_commit_files(
let diff = if let Some(other) = other {
get_compare_commits_diff(&repo, (id, other), None, None)?
} else {
get_commit_diff(repo_path, &repo, id, None, None)?
get_commit_diff(
&repo,
id,
None,
None,
Some(&get_stashes(repo_path)?.into_iter().collect()),
)?
};
let res = diff
@ -91,12 +97,12 @@ pub fn get_compare_commits_diff(
}
/// get diff of a commit to its first parent
pub fn get_commit_diff<'a>(
repo_path: &RepoPath,
pub(crate) fn get_commit_diff<'a>(
repo: &'a Repository,
id: CommitId,
pathspec: Option<String>,
options: Option<DiffOptions>,
stashes: Option<&HashSet<CommitId>>,
) -> Result<Diff<'a>> {
// scope_time!("get_commit_diff");
@ -128,14 +134,17 @@ pub fn get_commit_diff<'a>(
Some(&mut opts),
)?;
if is_stash_commit(repo_path, &id)? {
if stashes
.map(|stashes| stashes.contains(&id))
.unwrap_or_default()
{
if let Ok(untracked_commit) = commit.parent_id(2) {
let untracked_diff = get_commit_diff(
repo_path,
repo,
CommitId::new(untracked_commit),
pathspec,
options,
stashes,
)?;
diff.merge(&untracked_diff)?;

View file

@ -6,7 +6,10 @@ use super::{
CommitId, RepoPath,
};
use crate::{
error::Error, error::Result, hash, sync::repository::repo,
error::Error,
error::Result,
hash,
sync::{get_stashes, repository::repo},
};
use easy_cast::Conv;
use git2::{
@ -223,8 +226,13 @@ pub fn get_diff_commit(
let repo = repo(repo_path)?;
let work_dir = work_dir(&repo)?;
let diff =
get_commit_diff(repo_path, &repo, id, Some(p), options)?;
let diff = get_commit_diff(
&repo,
id,
Some(p),
options,
Some(&get_stashes(repo_path)?.into_iter().collect()),
)?;
raw_diff_to_file_diff(&diff, work_dir)
}

View file

@ -1,5 +1,4 @@
use super::CommitId;
use crate::sync::RepoPath;
use crate::{error::Result, sync::commit_files::get_commit_diff};
use git2::{Commit, Oid, Repository};
use std::{
@ -36,20 +35,17 @@ pub type LogWalkerFilter = Arc<
>;
///
pub fn diff_contains_file(
repo_path: RepoPath,
file_path: String,
) -> LogWalkerFilter {
pub fn diff_contains_file(file_path: String) -> LogWalkerFilter {
Arc::new(Box::new(
move |repo: &Repository,
commit_id: &CommitId|
-> Result<bool> {
let diff = get_commit_diff(
&repo_path,
repo,
*commit_id,
Some(file_path.clone()),
None,
None,
)?;
let contains_file = diff.deltas().len() > 0;
@ -224,9 +220,7 @@ mod tests {
let _third_commit_id = commit(&repo_path, "commit3").unwrap();
let repo_path_clone = repo_path.clone();
let diff_contains_baz =
diff_contains_file(repo_path_clone, "baz".into());
let diff_contains_baz = diff_contains_file("baz".into());
let mut items = Vec::new();
let mut walker = LogWalker::new(&repo, 100)?
@ -241,8 +235,7 @@ mod tests {
assert_eq!(items.len(), 0);
let diff_contains_bar =
diff_contains_file(repo_path, "bar".into());
let diff_contains_bar = diff_contains_file("bar".into());
let mut items = Vec::new();
let mut walker = LogWalker::new(&repo, 100)?

View file

@ -14,9 +14,7 @@ pub fn get_stashes(repo_path: &RepoPath) -> Result<Vec<CommitId>> {
scope_time!("get_stashes");
let mut repo = repo(repo_path)?;
let mut list = Vec::new();
repo.stash_foreach(|_index, _msg, id| {
list.push((*id).into());
true
@ -25,15 +23,6 @@ pub fn get_stashes(repo_path: &RepoPath) -> Result<Vec<CommitId>> {
Ok(list)
}
/// checks whether a given commit is a stash commit.
pub fn is_stash_commit(
repo_path: &RepoPath,
id: &CommitId,
) -> Result<bool> {
let stashes = get_stashes(repo_path)?;
Ok(stashes.contains(id))
}
///
pub fn stash_drop(
repo_path: &RepoPath,

View file

@ -117,10 +117,7 @@ impl FileRevlogComponent {
pub fn open(&mut self, open_request: FileRevOpen) -> Result<()> {
self.open_request = Some(open_request.clone());
let filter = diff_contains_file(
self.repo_path.borrow().clone(),
open_request.file_path,
);
let filter = diff_contains_file(open_request.file_path);
self.git_log = Some(AsyncLog::new(
self.repo_path.borrow().clone(),
&self.sender,