Skip to content

Commit 0912a46

Browse files
FernthedevByron
authored andcommitted
Squash 11 commits that get started with allowing to checkout a particular branch
1 parent 2f9f0ac commit 0912a46

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

gix/src/clone/checkout.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{clone::PrepareCheckout, Repository};
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 {
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 {
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 {
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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod blocking_io {
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 {
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 {

0 commit comments

Comments
 (0)