aboutsummaryrefslogtreecommitdiff
path: root/src/repo/git/checkout.rs
diff options
context:
space:
mode:
authorMax Audron <audron@cocaine.farm>2024-03-27 13:40:42 +0100
committerMax Audron <audron@cocaine.farm>2024-03-27 13:40:42 +0100
commitf7aca5859b3a40ec00c8789383e8ab84d7821ae6 (patch)
tree9a242aef7f0b0547949f4fefcff97eeaef1af356 /src/repo/git/checkout.rs
parentimplement basic cloning and updating with gix (diff)
reorganize repo git impls
Diffstat (limited to 'src/repo/git/checkout.rs')
-rw-r--r--src/repo/git/checkout.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/repo/git/checkout.rs b/src/repo/git/checkout.rs
new file mode 100644
index 0000000..418a0af
--- /dev/null
+++ b/src/repo/git/checkout.rs
@@ -0,0 +1,68 @@
+use super::{Repo, RepoError};
+
+use anyhow::Context;
+use gix::{
+ clone::checkout::main_worktree::ProgressId, interrupt::IS_INTERRUPTED, progress, remote, Id,
+ Progress,
+};
+
+use gix_index::{File, State};
+use tracing::debug;
+
+impl Repo {
+ #[tracing::instrument(level = "trace", skip(progress))]
+ pub fn checkout(
+ &self,
+ remote: remote::Name,
+ head: Id,
+ progress: &mut dyn progress::DynNestedProgress,
+ ) -> Result<(), RepoError> {
+ let repo = self.repo()?;
+
+ let workdir = repo.work_dir().ok_or(RepoError::NoWorktree)?;
+ let head_tree = head
+ .object()
+ .context("could not find object HEAD points to")?
+ .peel_to_tree()
+ .context("failed to peel HEAD object")?
+ .id();
+
+ let index = State::from_tree(&head_tree, &repo.objects).context("index from tree")?;
+ let mut index = File::from_state(index, repo.index_path());
+
+ let mut files =
+ progress.add_child_with_id("checkout".to_string(), ProgressId::CheckoutFiles.into());
+ let mut bytes =
+ progress.add_child_with_id("writing".to_string(), ProgressId::BytesWritten.into());
+
+ files.init(Some(index.entries().len()), progress::count("files"));
+ bytes.init(None, progress::bytes());
+
+ let start = std::time::Instant::now();
+
+ debug!("workdir: {:?}", workdir);
+ let opts = gix_worktree_state::checkout::Options::default();
+ let outcome = gix_worktree_state::checkout(
+ &mut index,
+ workdir,
+ repo.objects.clone().into_arc().unwrap(),
+ &files,
+ &bytes,
+ &IS_INTERRUPTED,
+ opts,
+ )
+ .context("checkout: failed");
+
+ files.show_throughput(start);
+ bytes.show_throughput(start);
+
+ debug!("outcome: {:?}", outcome);
+ debug!("is interrupted: {:?}", &gix::interrupt::IS_INTERRUPTED);
+
+ index
+ .write(Default::default())
+ .context("checkout: write index")?;
+
+ Ok(())
+ }
+}