summaryrefslogtreecommitdiffstats
path: root/asyncgit/src/sync/logwalker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'asyncgit/src/sync/logwalker.rs')
-rw-r--r--asyncgit/src/sync/logwalker.rs412
1 files changed, 206 insertions, 206 deletions
diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs
index b5caf946..bbc2c2b8 100644
--- a/asyncgit/src/sync/logwalker.rs
+++ b/asyncgit/src/sync/logwalker.rs
@@ -2,9 +2,9 @@ use super::CommitId;
use crate::error::Result;
use git2::{Commit, Oid, Repository};
use std::{
- cmp::Ordering,
- collections::{BinaryHeap, HashSet},
- sync::Arc,
+ cmp::Ordering,
+ collections::{BinaryHeap, HashSet},
+ sync::Arc,
};
struct TimeOrderedCommit<'a>(Commit<'a>);
@@ -12,237 +12,237 @@ struct TimeOrderedCommit<'a>(Commit<'a>);
impl<'a> Eq for TimeOrderedCommit<'a> {}
impl<'a> PartialEq for TimeOrderedCommit<'a> {
- fn eq(&self, other: &Self) -> bool {
- self.0.time().eq(&other.0.time())
- }
+ fn eq(&self, other: &Self) -> bool {
+ self.0.time().eq(&other.0.time())
+ }
}
impl<'a> PartialOrd for TimeOrderedCommit<'a> {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- self.0.time().partial_cmp(&other.0.time())
- }
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.0.time().partial_cmp(&other.0.time())
+ }
}
impl<'a> Ord for TimeOrderedCommit<'a> {
- fn cmp(&self, other: &Self) -> Ordering {
- self.0.time().cmp(&other.0.time())
- }
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.0.time().cmp(&other.0.time())
+ }
}
///
pub type LogWalkerFilter = Arc<
- Box<dyn Fn(&Repository, &CommitId) -> Result<bool> + Send + Sync>,
+ Box<dyn Fn(&Repository, &CommitId) -> Result<bool> + Send + Sync>,
>;
///
pub struct LogWalker<'a> {
- commits: BinaryHeap<TimeOrderedCommit<'a>>,
- visited: HashSet<Oid>,
- limit: usize,
- repo: &'a Repository,
- filter: Option<LogWalkerFilter>,
+ commits: BinaryHeap<TimeOrderedCommit<'a>>,
+ visited: HashSet<Oid>,
+ limit: usize,
+ repo: &'a Repository,
+ filter: Option<LogWalkerFilter>,
}
impl<'a> LogWalker<'a> {
- ///
- pub fn new(repo: &'a Repository, limit: usize) -> Result<Self> {
- let c = repo.head()?.peel_to_commit()?;
-
- let mut commits = BinaryHeap::with_capacity(10);
- commits.push(TimeOrderedCommit(c));
-
- Ok(Self {
- commits,
- limit,
- visited: HashSet::with_capacity(1000),
- repo,
- filter: None,
- })
- }
-
- ///
- pub fn filter(self, filter: Option<LogWalkerFilter>) -> Self {
- Self { filter, ..self }
- }
-
- ///
- pub fn read(&mut self, out: &mut Vec<CommitId>) -> Result<usize> {
- let mut count = 0_usize;
-
- while let Some(c) = self.commits.pop() {
- for p in c.0.parents() {
- self.visit(p);
- }
-
- let id: CommitId = c.0.id().into();
- let commit_should_be_included =
- if let Some(ref filter) = self.filter {
- filter(self.repo, &id)?
- } else {
- true
- };
-
- if commit_should_be_included {
- out.push(id);
- }
-
- count += 1;
- if count == self.limit {
- break;
- }
- }
-
- Ok(count)
- }
-
- //
- fn visit(&mut self, c: Commit<'a>) {
- if !self.visited.contains(&c.id()) {
- self.visited.insert(c.id());
- self.commits.push(TimeOrderedCommit(c));
- }
- }
+ ///
+ pub fn new(repo: &'a Repository, limit: usize) -> Result<Self> {
+ let c = repo.head()?.peel_to_commit()?;
+
+ let mut commits = BinaryHeap::with_capacity(10);
+ commits.push(TimeOrderedCommit(c));
+
+ Ok(Self {
+ commits,
+ limit,
+ visited: HashSet::with_capacity(1000),
+ repo,
+ filter: None,
+ })
+ }
+
+ ///
+ pub fn filter(self, filter: Option<LogWalkerFilter>) -> Self {
+ Self { filter, ..self }
+ }
+
+ ///
+ pub fn read(&mut self, out: &mut Vec<CommitId>) -> Result<usize> {
+ let mut count = 0_usize;
+
+ while let Some(c) = self.commits.pop() {
+ for p in c.0.parents() {
+ self.visit(p);
+ }
+
+ let id: CommitId = c.0.id().into();
+ let commit_should_be_included =
+ if let Some(ref filter) = self.filter {
+ filter(self.repo, &id)?
+ } else {
+ true
+ };
+
+ if commit_should_be_included {
+ out.push(id);
+ }
+
+ count += 1;
+ if count == self.limit {
+ break;
+ }
+ }
+
+ Ok(count)
+ }
+
+ //
+ fn visit(&mut self, c: Commit<'a>) {
+ if !self.visited.contains(&c.id()) {
+ self.visited.insert(c.id());
+ self.commits.push(TimeOrderedCommit(c));
+ }
+ }
}
#[cfg(test)]
mod tests {
- use super::*;
- use crate::error::Result;
- use crate::sync::{
- commit, commit_files::get_commit_diff, get_commits_info,
- stage_add_file, tests::repo_init_empty,
- };
- use pretty_assertions::assert_eq;
- use std::{fs::File, io::Write, path::Path};
-
- #[test]
- fn test_limit() -> Result<()> {
- let file_path = Path::new("foo");
- let (_td, repo) = repo_init_empty().unwrap();
- let root = repo.path().parent().unwrap();
- let repo_path = root.as_os_str().to_str().unwrap();
-
- File::create(&root.join(file_path))?.write_all(b"a")?;
- stage_add_file(repo_path, file_path).unwrap();
- commit(repo_path, "commit1").unwrap();
- File::create(&root.join(file_path))?.write_all(b"a")?;
- stage_add_file(repo_path, file_path).unwrap();
- let oid2 = commit(repo_path, "commit2").unwrap();
-
- let mut items = Vec::new();
- let mut walk = LogWalker::new(&repo, 1)?;
- walk.read(&mut items).unwrap();
-
- assert_eq!(items.len(), 1);
- assert_eq!(items[0], oid2.into());
-
- Ok(())
- }
-
- #[test]
- fn test_logwalker() -> Result<()> {
- let file_path = Path::new("foo");
- let (_td, repo) = repo_init_empty().unwrap();
- let root = repo.path().parent().unwrap();
- let repo_path = root.as_os_str().to_str().unwrap();
-
- File::create(&root.join(file_path))?.write_all(b"a")?;
- stage_add_file(repo_path, file_path).unwrap();
- commit(repo_path, "commit1").unwrap();
- File::create(&root.join(file_path))?.write_all(b"a")?;
- stage_add_file(repo_path, file_path).unwrap();
- let oid2 = commit(repo_path, "commit2").unwrap();
-
- let mut items = Vec::new();
- let mut walk = LogWalker::new(&repo, 100)?;
- walk.read(&mut items).unwrap();
-
- let info = get_commits_info(repo_path, &items, 50).unwrap();
- dbg!(&info);
-
- assert_eq!(items.len(), 2);
- assert_eq!(items[0], oid2.into());
-
- let mut items = Vec::new();
- walk.read(&mut items).unwrap();
-
- assert_eq!(items.len(), 0);
-
- Ok(())
- }
-
- #[test]
- fn test_logwalker_with_filter() -> Result<()> {
- let file_path = Path::new("foo");
- let second_file_path = Path::new("baz");
- let (_td, repo) = repo_init_empty().unwrap();
- let root = repo.path().parent().unwrap();
- let repo_path = root.as_os_str().to_str().unwrap();
-
- File::create(&root.join(file_path))?.write_all(b"a")?;
- stage_add_file(repo_path, file_path).unwrap();
-
- let _first_commit_id = commit(repo_path, "commit1").unwrap();
-
- File::create(&root.join(second_file_path))?
- .write_all(b"a")?;
- stage_add_file(repo_path, second_file_path).unwrap();
-
- let second_commit_id = commit(repo_path, "commit2").unwrap();
-
- File::create(&root.join(file_path))?.write_all(b"b")?;
- stage_add_file(repo_path, file_path).unwrap();
-
- let _third_commit_id = commit(repo_path, "commit3").unwrap();
-
- let diff_contains_baz = |repo: &Repository,
- commit_id: &CommitId|
- -> Result<bool> {
- let diff = get_commit_diff(
- &repo,
- *commit_id,
- Some("baz".into()),
- )?;
-
- let contains_file = diff.deltas().len() > 0;
-
- Ok(contains_file)
- };
-
- let mut items = Vec::new();
- let mut walker = LogWalker::new(&repo, 100)?
- .filter(Some(Arc::new(Box::new(diff_contains_baz))));
- walker.read(&mut items).unwrap();
+ use super::*;
+ use crate::error::Result;
+ use crate::sync::{
+ commit, commit_files::get_commit_diff, get_commits_info,
+ stage_add_file, tests::repo_init_empty,
+ };
+ use pretty_assertions::assert_eq;
+ use std::{fs::File, io::Write, path::Path};
+
+ #[test]
+ fn test_limit() -> Result<()> {
+ let file_path = Path::new("foo");
+ let (_td, repo) = repo_init_empty().unwrap();
+ let root = repo.path().parent().unwrap();
+ let repo_path = root.as_os_str().to_str().unwrap();
+
+ File::create(&root.join(file_path))?.write_all(b"a")?;
+ stage_add_file(repo_path, file_path).unwrap();
+ commit(repo_path, "commit1").unwrap();
+ File::create(&root.join(file_path))?.write_all(b"a")?;
+ stage_add_file(repo_path, file_path).unwrap();
+ let oid2 = commit(repo_path, "commit2").unwrap();
+
+ let mut items = Vec::new();
+ let mut walk = LogWalker::new(&repo, 1)?;
+ walk.read(&mut items).unwrap();
+
+ assert_eq!(items.len(), 1);
+ assert_eq!(items[0], oid2.into());
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_logwalker() -> Result<()> {
+ let file_path = Path::new("foo");
+ let (_td, repo) = repo_init_empty().unwrap();
+ let root = repo.path().parent().unwrap();
+ let repo_path = root.as_os_str().to_str().unwrap();
+
+ File::create(&root.join(file_path))?.write_all(b"a")?;
+ stage_add_file(repo_path, file_path).unwrap();
+ commit(repo_path, "commit1").unwrap();
+ File::create(&root.join(file_path))?.write_all(b"a")?;
+ stage_add_file(repo_path, file_path).unwrap();
+ let oid2 = commit(repo_path, "commit2").unwrap();
+
+ let mut items = Vec::new();
+ let mut walk = LogWalker::new(&repo, 100)?;
+ walk.read(&mut items).unwrap();
+
+ let info = get_commits_info(repo_path, &items, 50).unwrap();
+ dbg!(&info);
+
+ assert_eq!(items.len(), 2);
+ assert_eq!(items[0], oid2.into());
+
+ let mut items = Vec::new();
+ walk.read(&mut items).unwrap();
+
+ assert_eq!(items.len(), 0);
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_logwalker_with_filter() -> Result<()> {
+ let file_path = Path::new("foo");
+ let second_file_path = Path::new("baz");
+ let (_td, repo) = repo_init_empty().unwrap();
+ let root = repo.path().parent().unwrap();
+ let repo_path = root.as_os_str().to_str().unwrap();
+
+ File::create(&root.join(file_path))?.write_all(b"a")?;
+ stage_add_file(repo_path, file_path).unwrap();
+
+ let _first_commit_id = commit(repo_path, "commit1").unwrap();
+
+ File::create(&root.join(second_file_path))?
+ .write_all(b"a")?;
+ stage_add_file(repo_path, second_file_path).unwrap();
+
+ let second_commit_id = commit(repo_path, "commit2").unwrap();
+
+ File::create(&root.join(file_path))?.write_all(b"b")?;
+ stage_add_file(repo_path, file_path).unwrap();
+
+ let _third_commit_id = commit(repo_path, "commit3").unwrap();
+
+ let diff_contains_baz = |repo: &Repository,
+ commit_id: &CommitId|
+ -> Result<bool> {
+ let diff = get_commit_diff(
+ &repo,
+ *commit_id,
+ Some("baz".into()),
+ )?;
+
+ let contains_file = diff.deltas().len() > 0;
+
+ Ok(contains_file)
+ };
+
+ let mut items = Vec::new();
+ let mut walker = LogWalker::new(&repo, 100)?
+ .filter(Some(Arc::new(Box::new(diff_contains_baz))));
+ walker.read(&mut items).unwrap();
- assert_eq!(items.len(), 1);
- assert_eq!(items[0], second_commit_id.into());
+ assert_eq!(items.len(), 1);
+ assert_eq!(items[0], second_commit_id.into());
- let mut items = Vec::new();
- walker.read(&mut items).unwrap();
+ let mut items = Vec::new();
+ walker.read(&mut items).unwrap();
- assert_eq!(items.len(), 0);
+ assert_eq!(items.len(), 0);
- let diff_contains_bar = |repo: &Repository,
- commit_id: &CommitId|
- -> Result<bool> {
- let diff = get_commit_diff(
- &repo,
- *commit_id,
- Some("bar".into()),
- )?;
+ let diff_contains_bar = |repo: &Repository,
+ commit_id: &CommitId|
+ -> Result<bool> {
+ let diff = get_commit_diff(
+ &repo,
+ *commit_id,
+ Some("bar".into()),
+ )?;
- let contains_file = diff.deltas().len() > 0;
+ let contains_file = diff.deltas().len() > 0;
- Ok(contains_file)
- };
+ Ok(contains_file)
+ };
- let mut items = Vec::new();
- let mut walker = LogWalker::new(&repo, 100)?
- .filter(Some(Arc::new(Box::new(diff_contains_bar))));
- walker.read(&mut items).unwrap();
+ let mut items = Vec::new();
+ let mut walker = LogWalker::new(&repo, 100)?
+ .filter(Some(Arc::new(Box::new(diff_contains_bar))));
+ walker.read(&mut items).unwrap();
- assert_eq!(items.len(), 0);
+ assert_eq!(items.len(), 0);
- Ok(())
- }
+ Ok(())
+ }
}