From 86235efcf77346ff4b012497004dccc7380d70ac Mon Sep 17 00:00:00 2001 From: Max Audron Date: Wed, 26 Mar 2025 15:19:00 +0100 Subject: delete files removed from index during checkout --- src/repo/git/checkout.rs | 25 +++++++++++++++++++++++++ src/update/mod.rs | 7 ++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/repo/git/checkout.rs b/src/repo/git/checkout.rs index d4a9ced..44879a6 100644 --- a/src/repo/git/checkout.rs +++ b/src/repo/git/checkout.rs @@ -1,6 +1,7 @@ use super::{Repo, RepoError}; use anyhow::Context; +use gix::bstr::ByteSlice; use gix::{ clone::checkout::main_worktree::ProgressId, interrupt::IS_INTERRUPTED, progress, remote, Id, Progress, @@ -32,6 +33,13 @@ impl Repo { .context("index from tree")?; let mut index = File::from_state(index, repo.index_path()); + let status = repo + .status(gix::progress::Discard) + .unwrap() + .index(index.clone().into()) + .into_iter([]) + .unwrap(); + let mut files = progress.add_child_with_id("checkout".to_string(), ProgressId::CheckoutFiles.into()); let mut bytes = @@ -65,6 +73,23 @@ impl Repo { .write(Default::default()) .context("checkout: write index")?; + status + .filter_map(|item| item.ok()) + .filter_map(|item| match item { + gix::status::Item::IndexWorktree(_) => None, + gix::status::Item::TreeIndex(i) => Some(i), + }) + .for_each(|change| match change { + gix::diff::index::ChangeRef::Deletion { location, .. } + | gix::diff::index::ChangeRef::Rewrite { location, .. } => { + let mut path = std::path::PathBuf::from(workdir); + path.push(location.as_bstr().to_str().unwrap()); + debug!("removing deleted or renamed file: {:?}", path); + std::fs::remove_file(path).unwrap() + } + _ => (), + }); + Ok(()) } } diff --git a/src/update/mod.rs b/src/update/mod.rs index e3cd36a..e5e9f4c 100644 --- a/src/update/mod.rs +++ b/src/update/mod.rs @@ -46,13 +46,14 @@ impl Repo { let _fetched = self.fetch()?; let (remote, head) = self.default_remote_head()?; debug!("default remote and head: {:?} {:?}", remote, head); - // TODO do not update if there are unpushed commits - self.update_default_branch_ref(&remote, head)?; - debug!("updated default branch reference"); // TODO check out only if the default branch is currently checked out self.checkout(&remote, head, &mut progress)?; debug!("finished checkout"); + // TODO do not update if there are unpushed commits + self.update_default_branch_ref(&remote, head)?; + debug!("updated default branch reference"); + // let merged = repo.branches(Some(BranchType::Local))? // .filter_map(|x| x.ok()) // .try_fold(false, |mut merged, (mut branch, _)| { -- cgit v1.2.3