Skip to content

Commit 9eb8d47

Browse files
committed
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
1 parent e90656d commit 9eb8d47

File tree

5 files changed

+35
-39
lines changed

5 files changed

+35
-39
lines changed

Diff for: asyncgit/src/sync/commit_files.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
//! Functions for getting infos about files in commits
22
3-
use super::{
4-
diff::DiffOptions, stash::is_stash_commit, CommitId, RepoPath,
5-
};
3+
use super::{diff::DiffOptions, CommitId, RepoPath};
64
use crate::{
7-
error::Result, sync::repository::repo, StatusItem, StatusItemType,
5+
error::Result,
6+
sync::{get_stashes, repository::repo},
7+
StatusItem, StatusItemType,
88
};
99
use git2::{Diff, Repository};
1010
use scopetime::scope_time;
11-
use std::cmp::Ordering;
11+
use std::{cmp::Ordering, collections::HashSet};
1212

1313
/// get all files that are part of a commit
1414
pub fn get_commit_files(
@@ -23,7 +23,13 @@ pub fn get_commit_files(
2323
let diff = if let Some(other) = other {
2424
get_compare_commits_diff(&repo, (id, other), None, None)?
2525
} else {
26-
get_commit_diff(repo_path, &repo, id, None, None)?
26+
get_commit_diff(
27+
&repo,
28+
id,
29+
None,
30+
None,
31+
Some(&get_stashes(repo_path)?.into_iter().collect()),
32+
)?
2733
};
2834

2935
let res = diff
@@ -91,12 +97,12 @@ pub fn get_compare_commits_diff(
9197
}
9298

9399
/// get diff of a commit to its first parent
94-
pub fn get_commit_diff<'a>(
95-
repo_path: &RepoPath,
100+
pub(crate) fn get_commit_diff<'a>(
96101
repo: &'a Repository,
97102
id: CommitId,
98103
pathspec: Option<String>,
99104
options: Option<DiffOptions>,
105+
stashes: Option<&HashSet<CommitId>>,
100106
) -> Result<Diff<'a>> {
101107
// scope_time!("get_commit_diff");
102108

@@ -128,14 +134,17 @@ pub fn get_commit_diff<'a>(
128134
Some(&mut opts),
129135
)?;
130136

131-
if is_stash_commit(repo_path, &id)? {
137+
if stashes
138+
.map(|stashes| stashes.contains(&id))
139+
.unwrap_or_default()
140+
{
132141
if let Ok(untracked_commit) = commit.parent_id(2) {
133142
let untracked_diff = get_commit_diff(
134-
repo_path,
135143
repo,
136144
CommitId::new(untracked_commit),
137145
pathspec,
138146
options,
147+
stashes,
139148
)?;
140149

141150
diff.merge(&untracked_diff)?;

Diff for: asyncgit/src/sync/diff.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use super::{
66
CommitId, RepoPath,
77
};
88
use crate::{
9-
error::Error, error::Result, hash, sync::repository::repo,
9+
error::Error,
10+
error::Result,
11+
hash,
12+
sync::{get_stashes, repository::repo},
1013
};
1114
use easy_cast::Conv;
1215
use git2::{
@@ -223,8 +226,13 @@ pub fn get_diff_commit(
223226

224227
let repo = repo(repo_path)?;
225228
let work_dir = work_dir(&repo)?;
226-
let diff =
227-
get_commit_diff(repo_path, &repo, id, Some(p), options)?;
229+
let diff = get_commit_diff(
230+
&repo,
231+
id,
232+
Some(p),
233+
options,
234+
Some(&get_stashes(repo_path)?.into_iter().collect()),
235+
)?;
228236

229237
raw_diff_to_file_diff(&diff, work_dir)
230238
}

Diff for: asyncgit/src/sync/logwalker.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use super::CommitId;
2-
use crate::sync::RepoPath;
32
use crate::{error::Result, sync::commit_files::get_commit_diff};
43
use git2::{Commit, Oid, Repository};
54
use std::{
@@ -36,20 +35,17 @@ pub type LogWalkerFilter = Arc<
3635
>;
3736

3837
///
39-
pub fn diff_contains_file(
40-
repo_path: RepoPath,
41-
file_path: String,
42-
) -> LogWalkerFilter {
38+
pub fn diff_contains_file(file_path: String) -> LogWalkerFilter {
4339
Arc::new(Box::new(
4440
move |repo: &Repository,
4541
commit_id: &CommitId|
4642
-> Result<bool> {
4743
let diff = get_commit_diff(
48-
&repo_path,
4944
repo,
5045
*commit_id,
5146
Some(file_path.clone()),
5247
None,
48+
None,
5349
)?;
5450

5551
let contains_file = diff.deltas().len() > 0;
@@ -224,9 +220,7 @@ mod tests {
224220

225221
let _third_commit_id = commit(&repo_path, "commit3").unwrap();
226222

227-
let repo_path_clone = repo_path.clone();
228-
let diff_contains_baz =
229-
diff_contains_file(repo_path_clone, "baz".into());
223+
let diff_contains_baz = diff_contains_file("baz".into());
230224

231225
let mut items = Vec::new();
232226
let mut walker = LogWalker::new(&repo, 100)?
@@ -241,8 +235,7 @@ mod tests {
241235

242236
assert_eq!(items.len(), 0);
243237

244-
let diff_contains_bar =
245-
diff_contains_file(repo_path, "bar".into());
238+
let diff_contains_bar = diff_contains_file("bar".into());
246239

247240
let mut items = Vec::new();
248241
let mut walker = LogWalker::new(&repo, 100)?

Diff for: asyncgit/src/sync/stash.rs

-11
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ pub fn get_stashes(repo_path: &RepoPath) -> Result<Vec<CommitId>> {
1414
scope_time!("get_stashes");
1515

1616
let mut repo = repo(repo_path)?;
17-
1817
let mut list = Vec::new();
19-
2018
repo.stash_foreach(|_index, _msg, id| {
2119
list.push((*id).into());
2220
true
@@ -25,15 +23,6 @@ pub fn get_stashes(repo_path: &RepoPath) -> Result<Vec<CommitId>> {
2523
Ok(list)
2624
}
2725

28-
/// checks whether a given commit is a stash commit.
29-
pub fn is_stash_commit(
30-
repo_path: &RepoPath,
31-
id: &CommitId,
32-
) -> Result<bool> {
33-
let stashes = get_stashes(repo_path)?;
34-
Ok(stashes.contains(id))
35-
}
36-
3726
///
3827
pub fn stash_drop(
3928
repo_path: &RepoPath,

Diff for: src/components/file_revlog.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,7 @@ impl FileRevlogComponent {
117117
pub fn open(&mut self, open_request: FileRevOpen) -> Result<()> {
118118
self.open_request = Some(open_request.clone());
119119

120-
let filter = diff_contains_file(
121-
self.repo_path.borrow().clone(),
122-
open_request.file_path,
123-
);
120+
let filter = diff_contains_file(open_request.file_path);
124121
self.git_log = Some(AsyncLog::new(
125122
self.repo_path.borrow().clone(),
126123
&self.sender,

0 commit comments

Comments
 (0)