History

Squash 11 commits that get started with allowing to checkout a particular branch

FernTheDev committed 2 years ago

Commit 0912a461 parent 2f9f0ac2 files · +68 −4Browse files

Unified · Split

2 files
  1. gix/src/clone/checkout.rs +30 −3
  2. gix/tests/clone/mod.rs +38 −1
gix/src/clone/checkout.rs+30−3
@@ -5,6 +5,8 @@ use crate::{clone::PrepareCheckout, Repository}; · 4 unmodified lines
55 pub mod main_worktree {
66 use std::{path::PathBuf, sync::atomic::AtomicBool};
77
8+ use gix_ref::bstr::BStr;
9+
810 use crate::{clone::PrepareCheckout, Progress, Repository};
911
1012 /// The error returned by [`PrepareCheckout::main_worktree()`].
@@ -28,6 +30,8 @@ pub mod main_worktree { · 17 unmodified lines
2830 CheckoutOptions(#[from] crate::config::checkout_options::Error),
2931 #[error(transparent)]
3032 IndexCheckout(#[from] gix_worktree_state::checkout::Error),
33+ #[error(transparent)]
34+ Peel(#[from] crate::reference::peel::Error),
3135 #[error("Failed to reopen object database as Arc (only if thread-safety wasn't compiled in)")]
3236 OpenArcOdb(#[from] std::io::Error),
3337 #[error("The HEAD reference could not be located")]
@@ -72,13 +76,29 @@ pub mod main_worktree { · 38 unmodified lines
7276 P: gix_features::progress::NestedProgress,
7377 P::SubProgress: gix_features::progress::NestedProgress + 'static,
7478 {
75− self.main_worktree_inner(&mut progress, should_interrupt)
79+ self.main_worktree_inner(&mut progress, should_interrupt, None)
80+ }
81+
82+ /// Checkout the a worktree, determining how many threads to use by looking at `checkout.workers`, defaulting to using
83+ /// on thread per logical core.
84+ pub fn worktree<P>(
85+ &mut self,
86+ mut progress: P,
87+ should_interrupt: &AtomicBool,
88+ reference: Option<&BStr>,
89+ ) -> Result<(Repository, gix_worktree_state::checkout::Outcome), Error>
90+ where
91+ P: gix_features::progress::NestedProgress,
92+ P::SubProgress: gix_features::progress::NestedProgress + 'static,
93+ {
94+ self.main_worktree_inner(&mut progress, should_interrupt, reference)
7695 }
7796
7897 fn main_worktree_inner(
7998 &mut self,
8099 progress: &mut dyn gix_features::progress::DynNestedProgress,
81100 should_interrupt: &AtomicBool,
101+ reference: Option<&BStr>,
82102 ) -> Result<(Repository, gix_worktree_state::checkout::Outcome), Error> {
83103 let _span = gix_trace::coarse!("gix::clone::PrepareCheckout::main_worktree()");
84104 let repo = self
@@ -88,15 +108,22 @@ pub mod main_worktree { · 3 unmodified lines
88108 let workdir = repo.work_dir().ok_or_else(|| Error::BareRepository {
89109 git_dir: repo.git_dir().to_owned(),
90110 })?;
91− let root_tree = match repo.head()?.try_peel_to_id_in_place()? {
111+
112+ let root_tree_id = match reference {
113+ Some(reference_val) => Some(repo.find_reference(reference_val)?.peel_to_id_in_place()?),
114+ None => repo.head()?.try_peel_to_id_in_place()?,
115+ };
116+
117+ let root_tree = match root_tree_id {
92118 Some(id) => id.object().expect("downloaded from remote").peel_to_tree()?.id,
93119 None => {
94120 return Ok((
95121 self.repo.take().expect("still present"),
96122 gix_worktree_state::checkout::Outcome::default(),
97− ))
123+ ));
98124 }
99125 };
126+
100127 let index = gix_index::State::from_tree(&root_tree, &repo.objects, repo.config.protect_options()?)
101128 .map_err(|err| Error::IndexFromTree {
102129 id: root_tree,
gix/tests/clone/mod.rs+38−1
@@ -5,7 +5,7 @@ mod blocking_io { · 4 unmodified lines
55 use std::{borrow::Cow, sync::atomic::AtomicBool};
66
77 use gix::{
8− bstr::BString,
8+ bstr::{BStr, BString},
99 config::tree::{Clone, Core, Init, Key},
1010 remote::{
1111 fetch::{Shallow, SpecIndex},
@@ -507,6 +507,43 @@ mod blocking_io { · 495 unmodified lines
507507 }
508508 Ok(())
509509 }
510+ #[test]
511+ fn fetch_and_checkout_branch() -> crate::Result {
512+ let tmp = gix_testtools::tempfile::TempDir::new()?;
513+ let mut prepare = gix::clone::PrepareFetch::new(
514+ remote::repo("base").path(),
515+ tmp.path(),
516+ gix::create::Kind::WithWorktree,
517+ Default::default(),
518+ restricted(),
519+ )?;
520+ let (mut checkout, _out) =
521+ prepare.fetch_then_checkout(gix::progress::Discard, &std::sync::atomic::AtomicBool::default())?;
522+
523+ let branch_names = checkout.repo().branch_names();
524+ let target_branch: &BStr = "a".into();
525+ let branch_result = checkout.repo().find_reference(target_branch);
526+
527+ assert!(
528+ branch_result.is_ok(),
529+ "branch {target_branch} not found: {branch_result:?}. Available branches: {branch_names:?}"
530+ );
531+ let (repo, _) = checkout.worktree(
532+ gix::progress::Discard,
533+ &std::sync::atomic::AtomicBool::default(),
534+ Some("a".into()),
535+ )?;
536+
537+ let index = repo.index()?;
538+ assert_eq!(index.entries().len(), 1, "All entries are known as per HEAD tree");
539+
540+ let work_dir = repo.work_dir().expect("non-bare");
541+ for entry in index.entries() {
542+ let entry_path = work_dir.join(gix_path::from_bstr(entry.path(&index)));
543+ assert!(entry_path.is_file(), "{entry_path:?} not found on disk")
544+ }
545+ Ok(())
546+ }
510547
511548 #[test]
512549 fn fetch_and_checkout_empty_remote_repo() -> crate::Result {