diff --git a/gix/src/clone/access.rs b/gix/src/clone/access.rs
index ceada84472b..d9114f88532 100644
--- a/gix/src/clone/access.rs
+++ b/gix/src/clone/access.rs
@@ -67,8 +67,10 @@ impl PrepareFetch {
 
 impl Drop for PrepareFetch {
     fn drop(&mut self) {
-        if let Some(repo) = self.repo.take() {
-            std::fs::remove_dir_all(repo.work_dir().unwrap_or_else(|| repo.path())).ok();
+        if !self.leave_dirty {
+            if let Some(repo) = self.repo.take() {
+                std::fs::remove_dir_all(repo.work_dir().unwrap_or_else(|| repo.path())).ok();
+            }
         }
     }
 }
diff --git a/gix/src/clone/checkout.rs b/gix/src/clone/checkout.rs
index f2b3cd11251..307195d098b 100644
--- a/gix/src/clone/checkout.rs
+++ b/gix/src/clone/checkout.rs
@@ -172,8 +172,10 @@ impl PrepareCheckout {
 
 impl Drop for PrepareCheckout {
     fn drop(&mut self) {
-        if let Some(repo) = self.repo.take() {
-            std::fs::remove_dir_all(repo.work_dir().unwrap_or_else(|| repo.path())).ok();
+        if !self.leave_dirty {
+            if let Some(repo) = self.repo.take() {
+                std::fs::remove_dir_all(repo.work_dir().unwrap_or_else(|| repo.path())).ok();
+            }
         }
     }
 }
diff --git a/gix/src/clone/fetch/mod.rs b/gix/src/clone/fetch/mod.rs
index 1485871a159..d311b827ef4 100644
--- a/gix/src/clone/fetch/mod.rs
+++ b/gix/src/clone/fetch/mod.rs
@@ -227,6 +227,7 @@ impl PrepareFetch {
             crate::clone::PrepareCheckout {
                 repo: repo.into(),
                 ref_name: self.ref_name.clone(),
+                leave_dirty: self.leave_dirty,
             },
             fetch_outcome,
         ))
diff --git a/gix/src/clone/mod.rs b/gix/src/clone/mod.rs
index 920214d3f20..7b1f38f27da 100644
--- a/gix/src/clone/mod.rs
+++ b/gix/src/clone/mod.rs
@@ -37,6 +37,7 @@ pub struct PrepareFetch {
     /// The name of the reference to fetch. If `None`, the reference pointed to by `HEAD` will be checked out.
     #[cfg_attr(not(feature = "blocking-network-client"), allow(dead_code))]
     ref_name: Option<gix_ref::PartialName>,
+    leave_dirty: bool,
 }
 
 /// The error returned by [`PrepareFetch::new()`].
@@ -126,6 +127,7 @@ impl PrepareFetch {
             configure_connection: None,
             shallow: remote::fetch::Shallow::NoChange,
             ref_name: None,
+            leave_dirty: false,
         })
     }
 }
@@ -140,6 +142,7 @@ pub struct PrepareCheckout {
     pub(self) repo: Option<crate::Repository>,
     /// The name of the reference to check out. If `None`, the reference pointed to by `HEAD` will be checked out.
     pub(self) ref_name: Option<gix_ref::PartialName>,
+    pub(self) leave_dirty: bool,
 }
 
 // This module encapsulates functionality that works with both feature toggles. Can be combined with `fetch`
@@ -170,6 +173,13 @@ mod access_feat {
             self.fetch_options = opts;
             self
         }
+
+        /// Set whether to delete the repo directory when the PrepareFetch or PrepareCheckout
+        /// object is dropped.
+        pub fn with_leave_dirty(mut self, leave_dirty: bool) -> Self {
+            self.leave_dirty = leave_dirty;
+            self
+        }
     }
 }