simplify log walker

This commit is contained in:
Stephan Dilly 2021-06-03 23:55:30 +02:00
parent 3adcb4b8c8
commit e8c2dc25d4
4 changed files with 63 additions and 87 deletions

View file

@ -151,11 +151,10 @@ impl AsyncLog {
) -> Result<()> {
let mut entries = Vec::with_capacity(LIMIT_COUNT);
let r = repo(CWD)?;
let mut walker = LogWalker::new(&r);
let mut walker = LogWalker::new(&r, LIMIT_COUNT);
loop {
entries.clear();
let res_is_err =
walker.read(&mut entries, LIMIT_COUNT).is_err();
let res_is_err = walker.read(&mut entries).is_err();
if !res_is_err {
let mut current = arc_current.lock()?;

View file

@ -126,8 +126,8 @@ mod tests {
fn count_commits(repo: &Repository, max: usize) -> usize {
let mut items = Vec::new();
let mut walk = LogWalker::new(&repo);
walk.read(&mut items, max).unwrap();
let mut walk = LogWalker::new(&repo, max);
walk.read(&mut items).unwrap();
items.len()
}

View file

@ -1,55 +1,34 @@
#![allow(clippy::missing_panics_doc)]
use super::CommitId;
use crate::error::Result;
use git2::{Repository, Revwalk};
///
pub enum Mode {
HeadOnly,
AllRefs,
}
///
pub struct LogWalker<'a> {
repo: &'a Repository,
revwalk: Option<Revwalk<'a>>,
mode: Mode,
limit: usize,
}
impl<'a> LogWalker<'a> {
///
pub const fn new(repo: &'a Repository) -> Self {
pub const fn new(repo: &'a Repository, limit: usize) -> Self {
Self {
repo,
revwalk: None,
mode: Mode::HeadOnly,
limit,
}
}
///
pub const fn mode(self, mode: Mode) -> Self {
let mut res = self;
res.mode = mode;
res
}
///
pub fn read(
&mut self,
out: &mut Vec<CommitId>,
limit: usize,
) -> Result<usize> {
pub fn read(&mut self, out: &mut Vec<CommitId>) -> Result<usize> {
let mut count = 0_usize;
if self.revwalk.is_none() {
let mut walk = self.repo.revwalk()?;
// note: setting a sorting sifnificantly slows down big revwalks
if matches!(self.mode, Mode::HeadOnly) {
walk.push_head()?;
} else {
walk.push_glob("*")?;
}
walk.push_head()?;
self.revwalk = Some(walk);
}
@ -59,7 +38,7 @@ impl<'a> LogWalker<'a> {
out.push(id.into());
count += 1;
if count == limit {
if count == self.limit {
break;
}
}
@ -73,11 +52,9 @@ impl<'a> LogWalker<'a> {
mod tests {
use super::*;
use crate::sync::{
checkout_branch, commit, create_branch, get_commits_info,
stage_add_file,
tests::{repo_init_empty, write_commit_file_at},
commit, get_commits_info, stage_add_file,
tests::repo_init_empty,
};
use git2::Time;
use pretty_assertions::assert_eq;
use std::{fs::File, io::Write, path::Path};
@ -96,8 +73,8 @@ mod tests {
let oid2 = commit(repo_path, "commit2").unwrap();
let mut items = Vec::new();
let mut walk = LogWalker::new(&repo);
walk.read(&mut items, 1).unwrap();
let mut walk = LogWalker::new(&repo, 1);
walk.read(&mut items).unwrap();
assert_eq!(items.len(), 1);
assert_eq!(items[0], oid2.into());
@ -120,8 +97,8 @@ mod tests {
let oid2 = commit(repo_path, "commit2").unwrap();
let mut items = Vec::new();
let mut walk = LogWalker::new(&repo);
walk.read(&mut items, 100).unwrap();
let mut walk = LogWalker::new(&repo, 100);
walk.read(&mut items).unwrap();
let info = get_commits_info(repo_path, &items, 50).unwrap();
dbg!(&info);
@ -130,66 +107,66 @@ mod tests {
assert_eq!(items[0], oid2.into());
let mut items = Vec::new();
walk.read(&mut items, 100).unwrap();
walk.read(&mut items).unwrap();
assert_eq!(items.len(), 0);
Ok(())
}
fn walk_all_commits(repo: &Repository) -> Vec<CommitId> {
let mut items = Vec::new();
let mut walk = LogWalker::new(&repo).mode(Mode::AllRefs);
walk.read(&mut items, 10).unwrap();
items
}
// fn walk_all_commits(repo: &Repository) -> Vec<CommitId> {
// let mut items = Vec::new();
// let mut walk = LogWalker::new(&repo).mode(Mode::AllRefs);
// walk.read(&mut items, 10).unwrap();
// items
// }
#[test]
fn test_multiple_branches() {
let (td, repo) = repo_init_empty().unwrap();
let repo_path = td.path().to_string_lossy();
// #[test]
// fn test_multiple_branches() {
// let (td, repo) = repo_init_empty().unwrap();
// let repo_path = td.path().to_string_lossy();
let c1 = write_commit_file_at(
&repo,
"test.txt",
"",
"c1",
Time::new(1, 0),
);
// let c1 = write_commit_file_at(
// &repo,
// "test.txt",
// "",
// "c1",
// Time::new(1, 0),
// );
let items = walk_all_commits(&repo);
// let items = walk_all_commits(&repo);
assert_eq!(items, vec![c1]);
// assert_eq!(items, vec![c1]);
let b1 = create_branch(&repo_path, "b1").unwrap();
// let b1 = create_branch(&repo_path, "b1").unwrap();
let c2 = write_commit_file_at(
&repo,
"test2.txt",
"",
"c2",
Time::new(2, 0),
);
// let c2 = write_commit_file_at(
// &repo,
// "test2.txt",
// "",
// "c2",
// Time::new(2, 0),
// );
let items = walk_all_commits(&repo);
assert_eq!(items, vec![c2, c1]);
// let items = walk_all_commits(&repo);
// assert_eq!(items, vec![c2, c1]);
let _b2 = create_branch(&repo_path, "b2").unwrap();
// let _b2 = create_branch(&repo_path, "b2").unwrap();
let c3 = write_commit_file_at(
&repo,
"test3.txt",
"",
"c3",
Time::new(3, 0),
);
// let c3 = write_commit_file_at(
// &repo,
// "test3.txt",
// "",
// "c3",
// Time::new(3, 0),
// );
let items = walk_all_commits(&repo);
assert_eq!(items, vec![c2, c3, c1]);
// let items = walk_all_commits(&repo);
// assert_eq!(items, vec![c2, c3, c1]);
checkout_branch(&repo_path, &b1).unwrap();
// checkout_branch(&repo_path, &b1).unwrap();
let items = walk_all_commits(&repo);
assert_eq!(items, vec![c2, c3, c1]);
}
// let items = walk_all_commits(&repo);
// assert_eq!(items, vec![c2, c3, c1]);
// }
}

View file

@ -274,7 +274,7 @@ mod tests {
max_count: usize,
) -> Vec<CommitId> {
let mut commit_ids = Vec::<CommitId>::new();
LogWalker::new(r).read(&mut commit_ids, max_count).unwrap();
LogWalker::new(r, max_count).read(&mut commit_ids).unwrap();
commit_ids
}