diff --git a/asyncgit/src/sync/branch/mod.rs b/asyncgit/src/sync/branch/mod.rs index edfd0730..5bd364ac 100644 --- a/asyncgit/src/sync/branch/mod.rs +++ b/asyncgit/src/sync/branch/mod.rs @@ -325,7 +325,7 @@ pub fn delete_branch( } /// creates a new branch pointing to current HEAD commit and updating HEAD to new branch -pub fn create_branch(repo_path: &str, name: &str) -> Result<()> { +pub fn create_branch(repo_path: &str, name: &str) -> Result { scope_time!("create_branch"); let repo = utils::repo(repo_path)?; @@ -338,7 +338,7 @@ pub fn create_branch(repo_path: &str, name: &str) -> Result<()> { let branch_ref_name = bytes2string(branch_ref.name_bytes())?; repo.set_head(branch_ref_name.as_str())?; - Ok(()) + Ok(branch_ref_name) } #[cfg(test)] diff --git a/asyncgit/src/sync/logwalker.rs b/asyncgit/src/sync/logwalker.rs index 8ad2b444..870c8d63 100644 --- a/asyncgit/src/sync/logwalker.rs +++ b/asyncgit/src/sync/logwalker.rs @@ -2,10 +2,17 @@ use super::CommitId; use crate::error::Result; use git2::{Repository, Revwalk, Sort}; +/// +pub enum Mode { + HeadOnly, + AllRefs, +} + /// pub struct LogWalker<'a> { repo: &'a Repository, revwalk: Option>, + mode: Mode, } impl<'a> LogWalker<'a> { @@ -14,9 +21,17 @@ impl<'a> LogWalker<'a> { Self { repo, revwalk: None, + mode: Mode::HeadOnly, } } + /// + pub const fn mode(self, mode: Mode) -> Self { + let mut res = self; + res.mode = mode; + res + } + /// pub fn read( &mut self, @@ -28,7 +43,12 @@ impl<'a> LogWalker<'a> { if self.revwalk.is_none() { let mut walk = self.repo.revwalk()?; - walk.push_head()?; + if matches!(self.mode, Mode::HeadOnly) { + walk.push_head()?; + } else { + walk.push_glob("*")?; + } + walk.set_sorting(Sort::TIME)?; self.revwalk = Some(walk); @@ -53,9 +73,12 @@ impl<'a> LogWalker<'a> { mod tests { use super::*; use crate::sync::{ - commit, get_commits_info, stage_add_file, - tests::repo_init_empty, + checkout_branch, commit, create_branch, get_commits_info, + stage_add_file, + tests::{repo_init_empty, write_commit_file_at}, }; + use git2::Time; + use pretty_assertions::assert_eq; use std::{fs::File, io::Write, path::Path}; #[test] @@ -113,4 +136,60 @@ mod tests { Ok(()) } + + fn walk_all_commits(repo: &Repository) -> Vec { + 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(); + + let c1 = write_commit_file_at( + &repo, + "test.txt", + "", + "c1", + Time::new(1, 0), + ); + + let items = walk_all_commits(&repo); + + assert_eq!(items, vec![c1]); + + let b1 = create_branch(&repo_path, "b1").unwrap(); + + 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 _b2 = create_branch(&repo_path, "b2").unwrap(); + + let c3 = write_commit_file_at( + &repo, + "test3.txt", + "", + "c3", + Time::new(3, 0), + ); + + let items = walk_all_commits(&repo); + assert_eq!(items, vec![c3, c2, c1]); + + checkout_branch(&repo_path, &b1).unwrap(); + + let items = walk_all_commits(&repo); + assert_eq!(items, vec![c3, c2, c1]); + } }