Skip to content

Commit 5394f3c

Browse files
committed
get worktree status in parallel
This can take a long time on massive repos.
1 parent 4085053 commit 5394f3c

File tree

2 files changed

+53
-43
lines changed

2 files changed

+53
-43
lines changed

src/info/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::cli::{self, Config};
22
use crate::ui::get_ascii_colors;
33
use crate::ui::text_colors::TextColors;
4-
use anyhow::Result;
4+
use anyhow::{Context, Result};
55
use author::Author;
66
use deps::DependencyDetector;
77
use git2::Repository;
@@ -166,8 +166,15 @@ impl Info {
166166
config.number_of_authors,
167167
)?;
168168
let (repo_name, repo_url) = internal_repo.get_name_and_url()?;
169+
let pending_changes = std::thread::spawn({
170+
let git_dir = repo.path().to_owned();
171+
move || {
172+
let repo = git2::Repository::open(git_dir)?;
173+
repo::get_pending_changes(&repo)
174+
}
175+
});
176+
169177
let head_refs = internal_repo.get_head_refs()?;
170-
let pending_changes = internal_repo.get_pending_changes()?;
171178
let version = internal_repo.get_version()?;
172179
let git_username = internal_repo.get_git_username()?;
173180
let number_of_tags = internal_repo.get_number_of_tags()?;
@@ -202,7 +209,10 @@ impl Info {
202209
number_of_tags,
203210
number_of_branches,
204211
head_refs,
205-
pending_changes,
212+
pending_changes: pending_changes
213+
.join()
214+
.ok()
215+
.context("BUG: panic in pending-changes thread")??,
206216
version,
207217
creation_date,
208218
languages,

src/info/repo.rs

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -205,46 +205,6 @@ impl<'a> Repo<'a> {
205205
Ok(version_name)
206206
}
207207

208-
pub fn get_pending_changes(&self) -> Result<String> {
209-
let statuses = self.git2_repo.statuses(Some(
210-
StatusOptions::default()
211-
.show(StatusShow::Workdir)
212-
.update_index(true)
213-
.include_untracked(true)
214-
.renames_head_to_index(true)
215-
.recurse_untracked_dirs(true),
216-
))?;
217-
218-
let (added, deleted, modified) =
219-
statuses
220-
.iter()
221-
.fold((0, 0, 0), |(added, deleted, modified), e| {
222-
let s: Status = e.status();
223-
if s.is_index_new() || s.is_wt_new() {
224-
(added + 1, deleted, modified)
225-
} else if s.is_index_deleted() || s.is_wt_deleted() {
226-
(added, deleted + 1, modified)
227-
} else {
228-
(added, deleted, modified + 1)
229-
}
230-
});
231-
232-
let mut result = String::new();
233-
if modified > 0 {
234-
result = format!("{}+-", modified)
235-
}
236-
237-
if added > 0 {
238-
result = format!("{} {}+", result, added);
239-
}
240-
241-
if deleted > 0 {
242-
result = format!("{} {}-", result, deleted);
243-
}
244-
245-
Ok(result.trim().into())
246-
}
247-
248208
pub fn get_name_and_url(&self) -> Result<(String, String)> {
249209
let config = self.git2_repo.config()?;
250210
let mut remote_origin_url: Option<String> = None;
@@ -397,3 +357,43 @@ mod tests {
397357
assert_eq!(result, "1970-01-01T00:00:00Z");
398358
}
399359
}
360+
361+
pub fn get_pending_changes(repo: &git2::Repository) -> Result<String> {
362+
let statuses = repo.statuses(Some(
363+
StatusOptions::default()
364+
.show(StatusShow::Workdir)
365+
.update_index(true)
366+
.include_untracked(true)
367+
.renames_head_to_index(true)
368+
.recurse_untracked_dirs(true),
369+
))?;
370+
371+
let (added, deleted, modified) =
372+
statuses
373+
.iter()
374+
.fold((0, 0, 0), |(added, deleted, modified), e| {
375+
let s: Status = e.status();
376+
if s.is_index_new() || s.is_wt_new() {
377+
(added + 1, deleted, modified)
378+
} else if s.is_index_deleted() || s.is_wt_deleted() {
379+
(added, deleted + 1, modified)
380+
} else {
381+
(added, deleted, modified + 1)
382+
}
383+
});
384+
385+
let mut result = String::new();
386+
if modified > 0 {
387+
result = format!("{}+-", modified)
388+
}
389+
390+
if added > 0 {
391+
result = format!("{} {}+", result, added);
392+
}
393+
394+
if deleted > 0 {
395+
result = format!("{} {}-", result, deleted);
396+
}
397+
398+
Ok(result.trim().into())
399+
}

0 commit comments

Comments
 (0)