Skip to content

Commit cb53324

Browse files
committed
make stat extractions interruptable (#470)
1 parent 84eb777 commit cb53324

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

gitoxide-core/src/hours.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,18 @@ where
6666
});
6767
let stat_counter = stat_progress.as_ref().and_then(|p| p.counter());
6868

69-
let change_progress = needs_stats
70-
.then(|| progress.add_child("analyzing changes"))
71-
.map(|mut p| {
72-
p.init(None, progress::count("files"));
73-
p
74-
});
69+
let change_progress = needs_stats.then(|| progress.add_child("find changes")).map(|mut p| {
70+
p.init(None, progress::count("modified files"));
71+
p
72+
});
7573
let change_counter = change_progress.as_ref().and_then(|p| p.counter());
7674

75+
let lines_progress = line_stats.then(|| progress.add_child("find changes")).map(|mut p| {
76+
p.init(None, progress::count("diff lines"));
77+
p
78+
});
79+
let lines_counter = lines_progress.as_ref().and_then(|p| p.counter());
80+
7781
let mut progress = progress.add_child("traverse commit graph");
7882
progress.init(None, progress::count("commits"));
7983

@@ -134,6 +138,7 @@ where
134138
scope.spawn({
135139
let commit_counter = stat_counter.clone();
136140
let change_counter = change_counter.clone();
141+
let lines_counter = lines_counter.clone();
137142
let mut repo = repo.clone();
138143
repo.object_cache_size_if_unset(4 * 1024 * 1024);
139144
let rx = rx.clone();
@@ -143,6 +148,9 @@ where
143148
if let Some(c) = commit_counter.as_ref() {
144149
c.fetch_add(1, Ordering::SeqCst);
145150
}
151+
if git::interrupt::is_triggered() {
152+
return Ok(out);
153+
}
146154
let mut files = FileStats::default();
147155
let mut lines = LineStats::default();
148156
let from = match parent_commit {
@@ -173,15 +181,23 @@ where
173181
files.added += 1
174182
}
175183
if let Ok(blob) = id.object() {
176-
lines.added = blob.data.lines_with_terminator().count();
184+
let nl = blob.data.lines_with_terminator().count();
185+
lines.added += nl;
186+
if let Some(c) = lines_counter.as_ref() {
187+
c.fetch_add(nl, Ordering::SeqCst);
188+
}
177189
}
178190
}
179191
Deletion { entry_mode, id } => {
180192
if entry_mode.is_no_tree() {
181193
files.removed += 1
182194
}
183195
if let Ok(blob) = id.object() {
184-
lines.removed = blob.data.lines_with_terminator().count();
196+
let nl = blob.data.lines_with_terminator().count();
197+
lines.removed += nl;
198+
if let Some(c) = lines_counter.as_ref() {
199+
c.fetch_add(nl, Ordering::SeqCst);
200+
}
185201
}
186202
}
187203
Modification { entry_mode, .. } => {
@@ -191,16 +207,26 @@ where
191207
if line_stats {
192208
if let Some(Ok(diff)) = change.event.diff() {
193209
use git::diff::lines::similar::ChangeTag::*;
210+
let mut nl = 0;
194211
for change in diff
195212
.text(git::diff::lines::Algorithm::Myers)
196213
.iter_all_changes()
197214
{
198215
match change.tag() {
199-
Delete => lines.removed += 1,
200-
Insert => lines.added += 1,
216+
Delete => {
217+
lines.removed += 1;
218+
nl += 1;
219+
}
220+
Insert => {
221+
lines.added += 1;
222+
nl += 1
223+
}
201224
Equal => {}
202225
}
203226
}
227+
if let Some(c) = lines_counter.as_ref() {
228+
c.fetch_add(nl, Ordering::SeqCst);
229+
}
204230
}
205231
}
206232
}
@@ -260,6 +286,9 @@ where
260286
let mut stats = Vec::new();
261287
for handle in stat_threads {
262288
stats.extend(handle.join().expect("no panic")?);
289+
if git::interrupt::is_triggered() {
290+
bail!("Cancelled by user");
291+
}
263292
}
264293
stats.sort_by_key(|t| t.0);
265294
progress.show_throughput(start);
@@ -270,6 +299,9 @@ where
270299
if let Some(mut progress) = change_progress {
271300
progress.show_throughput(start);
272301
}
302+
if let Some(mut progress) = lines_progress {
303+
progress.show_throughput(start);
304+
}
273305

274306
Ok((
275307
commit_thread.join().expect("no panic")?,

0 commit comments

Comments
 (0)