| @@ -5,6 +5,8 @@ use crate::{clone::PrepareCheckout, Repository}; · 4 unmodified lines |
| 5 | 5 | pub mod main_worktree { |
| 6 | 6 | use std::{path::PathBuf, sync::atomic::AtomicBool}; |
| 7 | 7 | |
| 8 | + use gix_ref::bstr::BStr; |
| 9 | + |
| 8 | 10 | use crate::{clone::PrepareCheckout, Progress, Repository}; |
| 9 | 11 | |
| 10 | 12 | /// The error returned by [`PrepareCheckout::main_worktree()`]. |
| @@ -28,6 +30,8 @@ pub mod main_worktree { · 17 unmodified lines |
| 28 | 30 | CheckoutOptions(#[from] crate::config::checkout_options::Error), |
| 29 | 31 | #[error(transparent)] |
| 30 | 32 | IndexCheckout(#[from] gix_worktree_state::checkout::Error), |
| 33 | + #[error(transparent)] |
| 34 | + Peel(#[from] crate::reference::peel::Error), |
| 31 | 35 | #[error("Failed to reopen object database as Arc (only if thread-safety wasn't compiled in)")] |
| 32 | 36 | OpenArcOdb(#[from] std::io::Error), |
| 33 | 37 | #[error("The HEAD reference could not be located")] |
| @@ -72,13 +76,29 @@ pub mod main_worktree { · 38 unmodified lines |
| 72 | 76 | P: gix_features::progress::NestedProgress, |
| 73 | 77 | P::SubProgress: gix_features::progress::NestedProgress + 'static, |
| 74 | 78 | { |
| 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) |
| 76 | 95 | } |
| 77 | 96 | |
| 78 | 97 | fn main_worktree_inner( |
| 79 | 98 | &mut self, |
| 80 | 99 | progress: &mut dyn gix_features::progress::DynNestedProgress, |
| 81 | 100 | should_interrupt: &AtomicBool, |
| 101 | + reference: Option<&BStr>, |
| 82 | 102 | ) -> Result<(Repository, gix_worktree_state::checkout::Outcome), Error> { |
| 83 | 103 | let _span = gix_trace::coarse!("gix::clone::PrepareCheckout::main_worktree()"); |
| 84 | 104 | let repo = self |
| @@ -88,15 +108,22 @@ pub mod main_worktree { · 3 unmodified lines |
| 88 | 108 | let workdir = repo.work_dir().ok_or_else(|| Error::BareRepository { |
| 89 | 109 | git_dir: repo.git_dir().to_owned(), |
| 90 | 110 | })?; |
| 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 { |
| 92 | 118 | Some(id) => id.object().expect("downloaded from remote").peel_to_tree()?.id, |
| 93 | 119 | None => { |
| 94 | 120 | return Ok(( |
| 95 | 121 | self.repo.take().expect("still present"), |
| 96 | 122 | gix_worktree_state::checkout::Outcome::default(), |
| 97 | | − )) |
| 123 | + )); |
| 98 | 124 | } |
| 99 | 125 | }; |
| 126 | + |
| 100 | 127 | let index = gix_index::State::from_tree(&root_tree, &repo.objects, repo.config.protect_options()?) |
| 101 | 128 | .map_err(|err| Error::IndexFromTree { |
| 102 | 129 | id: root_tree, |