diff options
author | Canop <cano.petrole@gmail.com> | 2020-02-03 21:25:19 +0100 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2020-02-03 21:25:19 +0100 |
commit | 8c945f5cc133e72b6c4fad1f69c202cf74eefbed (patch) | |
tree | cbd884729bbb8bf819a10c48ac752029e36216ff | |
parent | 78c4df297466a58812093ee43a5d270065746c1e (diff) |
much faster :git_status
All git statuses are itered at once in order to avoid calling
the libgit2 library several times (those calls are very costly)
-rw-r--r-- | src/browser_states.rs | 4 | ||||
-rw-r--r-- | src/git_status.rs | 36 | ||||
-rw-r--r-- | src/tree_build/builder.rs | 12 |
3 files changed, 26 insertions, 26 deletions
diff --git a/src/browser_states.rs b/src/browser_states.rs index 00414ec..1181ee3 100644 --- a/src/browser_states.rs +++ b/src/browser_states.rs @@ -218,10 +218,6 @@ fn make_opener( impl AppState for BrowserState { fn has_pending_task(&self) -> bool { - debug!( - "CHECK self.displayed_tree().is_missing_git_status_computation() = {}", - self.displayed_tree().is_missing_git_status_computation(), - ); self.pending_pattern.is_some() || self.displayed_tree().has_dir_missing_size() || self.displayed_tree().is_missing_git_status_computation() diff --git a/src/git_status.rs b/src/git_status.rs index 7da51d1..ecfa7d4 100644 --- a/src/git_status.rs +++ b/src/git_status.rs @@ -6,7 +6,7 @@ use { Status, }, std::{ - collections::HashSet, + collections::HashMap, path::{ Path, PathBuf, @@ -37,31 +37,35 @@ impl LineGitStatus { } pub struct LineStatusComputer { - repo: Repository, - repo_path: PathBuf, - //interesting_paths: HashSet<PathBuf>, + interesting_statuses: HashMap<PathBuf, Status>, } impl LineStatusComputer { pub fn from(repo: Repository) -> Self { + let repo_path = repo.path().parent().unwrap().to_path_buf(); + let mut interesting_statuses = HashMap::new(); + if let Ok(statuses) = &repo.statuses(None) { + for entry in statuses.iter() { + let status = entry.status(); + if status.intersects(INTERESTING) { + if let Some(path) = entry.path() { + let path = repo_path.join(path); + interesting_statuses.insert(path, status); + } + } + } + } else { + debug!("get statuses failed"); + } Self { - repo_path: repo.path().parent().unwrap().to_path_buf(), - repo, - //interesting_paths: HashSet::new(), + interesting_statuses, } } pub fn line_status(&self, path: &Path) -> Option<LineGitStatus> { - pathdiff::diff_paths(path, &self.repo_path) - .and_then(|relative_path| LineGitStatus::from(&self.repo, &relative_path)) + self.interesting_statuses.get(path).map(|&status| LineGitStatus { status }) } pub fn is_interesting(&self, path: &Path) -> bool { - match self.line_status(path) { - Some(lgs) => lgs.is_interesting(), - None => false, - } + self.interesting_statuses.contains_key(path) } - //pub fn load_interesting_paths(&mut self) { - - //} } diff --git a/src/tree_build/builder.rs b/src/tree_build/builder.rs index 84f1448..b071fc2 100644 --- a/src/tree_build/builder.rs +++ b/src/tree_build/builder.rs @@ -74,7 +74,11 @@ impl TreeBuilder { let mut git_ignorer = time!(Debug, "GitIgnorer::new", GitIgnorer::new()); let root_ignore_chain = git_ignorer.root_chain(&path); let line_status_computer = if options.filter_by_git_status || options.show_git_file_info { - Repository::discover(&path).ok().map(LineStatusComputer::from) + time!( + Debug, + "init line_status_computer", + Repository::discover(&path).ok().map(LineStatusComputer::from), + ) } else { None }; @@ -420,11 +424,7 @@ impl TreeBuilder { // it would make no sense to keep only files having a git status and // not display that type for mut line in tree.lines.iter_mut() { - line.git_status = time!( - Debug, - "LineGitStatus", - computer.line_status(&line.path), - ); + line.git_status = computer.line_status(&line.path); } } tree |