diff --git a/gitoxide-core/src/repository/archive.rs b/gitoxide-core/src/repository/archive.rs index d064e952c4c..c229fe976b8 100644 --- a/gitoxide-core/src/repository/archive.rs +++ b/gitoxide-core/src/repository/archive.rs @@ -30,7 +30,7 @@ pub fn stream( let (mut stream, index) = repo.worktree_stream(tree)?; if !add_paths.is_empty() { let root = gix::path::realpath( - repo.work_dir() + repo.workdir() .ok_or_else(|| anyhow!("Adding files requires a worktree directory that contains them"))?, )?; for path in add_paths { diff --git a/gitoxide-core/src/repository/attributes/query.rs b/gitoxide-core/src/repository/attributes/query.rs index 72fac97ac2c..af0b90f9185 100644 --- a/gitoxide-core/src/repository/attributes/query.rs +++ b/gitoxide-core/src/repository/attributes/query.rs @@ -83,7 +83,7 @@ pub(crate) mod function { gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping .adjust_for_bare(repo.is_bare()), )?; - let workdir = repo.work_dir(); + let workdir = repo.workdir(); for pattern in pathspec.search().patterns() { let path = pattern.path(); let entry = cache.at_entry( diff --git a/gitoxide-core/src/repository/attributes/validate_baseline.rs b/gitoxide-core/src/repository/attributes/validate_baseline.rs index 42dc108c9e6..51de5d5382b 100644 --- a/gitoxide-core/src/repository/attributes/validate_baseline.rs +++ b/gitoxide-core/src/repository/attributes/validate_baseline.rs @@ -114,7 +114,7 @@ pub(crate) mod function { }; let work_dir = ignore .then(|| { - repo.work_dir() + repo.workdir() .map(ToOwned::to_owned) .ok_or_else(|| anyhow!("repository at {:?} must have a worktree checkout", repo.path())) }) @@ -249,7 +249,7 @@ pub(crate) mod function { } bail!( "{}: Validation failed with {} mismatches out of {}", - gix::path::realpath(repo.work_dir().unwrap_or(repo.git_dir()))?.display(), + gix::path::realpath(repo.workdir().unwrap_or(repo.git_dir()))?.display(), mismatches.len(), progress.counter().load(Ordering::Relaxed) ); diff --git a/gitoxide-core/src/repository/clean.rs b/gitoxide-core/src/repository/clean.rs index bd5939d45c1..1146f4b2fb0 100644 --- a/gitoxide-core/src/repository/clean.rs +++ b/gitoxide-core/src/repository/clean.rs @@ -53,7 +53,7 @@ pub(crate) mod function { if format != OutputFormat::Human { bail!("JSON output isn't implemented yet"); } - let Some(workdir) = repo.work_dir() else { + let Some(workdir) = repo.workdir() else { bail!("Need a worktree to clean, this is a bare repository"); }; diff --git a/gitoxide-core/src/repository/exclude.rs b/gitoxide-core/src/repository/exclude.rs index 197e6d5d3b7..f2cd35be0d9 100644 --- a/gitoxide-core/src/repository/exclude.rs +++ b/gitoxide-core/src/repository/exclude.rs @@ -60,7 +60,7 @@ pub fn query( let mut pathspec = repo.pathspec( true, patterns.iter(), - repo.work_dir().is_some(), + repo.workdir().is_some(), &index, gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping.adjust_for_bare(repo.is_bare()), )?; @@ -82,12 +82,12 @@ pub fn query( let pathspec = repo.pathspec( true, patterns.iter(), - repo.work_dir().is_some(), + repo.workdir().is_some(), &index, gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping .adjust_for_bare(repo.is_bare()), )?; - let workdir = repo.work_dir(); + let workdir = repo.workdir(); for pattern in pathspec.search().patterns() { let path = pattern.path(); let entry = cache.at_entry( diff --git a/gitoxide-core/src/repository/merge/file.rs b/gitoxide-core/src/repository/merge/file.rs index 120eff0135b..7e183c8a9e6 100644 --- a/gitoxide-core/src/repository/merge/file.rs +++ b/gitoxide-core/src/repository/merge/file.rs @@ -40,7 +40,7 @@ pub fn file( let base_id = repo.rev_parse_single(base.as_bstr()).ok(); let ours_id = repo.rev_parse_single(ours.as_bstr()).ok(); let theirs_id = repo.rev_parse_single(theirs.as_bstr()).ok(); - let roots = worktree_roots(base_id, ours_id, theirs_id, repo.work_dir())?; + let roots = worktree_roots(base_id, ours_id, theirs_id, repo.workdir())?; let mut cache = repo.merge_resource_cache(roots)?; let null = repo.object_hash().null(); diff --git a/gix-fs/src/snapshot.rs b/gix-fs/src/snapshot.rs index 2b21d0d9f21..638096db843 100644 --- a/gix-fs/src/snapshot.rs +++ b/gix-fs/src/snapshot.rs @@ -1,7 +1,6 @@ // TODO: tests -use std::ops::Deref; - use gix_features::threading::{get_mut, get_ref, MutableOnDemand, OwnShared}; +use std::ops::Deref; /// A structure holding enough information to reload a value if its on-disk representation changes as determined by its modified time. #[derive(Debug)] @@ -39,6 +38,16 @@ impl Clone for FileSnapshot { } } +impl FileSnapshot { + /// Return the contained instance if nobody else is holding it, or clone it otherwise. + pub fn into_owned_or_cloned(self: OwnShared) -> T { + match OwnShared::try_unwrap(self) { + Ok(this) => this.value, + Err(this) => this.value.clone(), + } + } +} + /// A snapshot of a resource which is up-to-date in the moment it is retrieved. pub type SharedFileSnapshot = OwnShared>; diff --git a/gix-fs/tests/capabilities/mod.rs b/gix-fs/tests/fs/capabilities.rs similarity index 100% rename from gix-fs/tests/capabilities/mod.rs rename to gix-fs/tests/fs/capabilities.rs diff --git a/gix-fs/tests/dir/create.rs b/gix-fs/tests/fs/dir/create.rs similarity index 100% rename from gix-fs/tests/dir/create.rs rename to gix-fs/tests/fs/dir/create.rs diff --git a/gix-fs/tests/dir/mod.rs b/gix-fs/tests/fs/dir/mod.rs similarity index 100% rename from gix-fs/tests/dir/mod.rs rename to gix-fs/tests/fs/dir/mod.rs diff --git a/gix-fs/tests/dir/remove.rs b/gix-fs/tests/fs/dir/remove.rs similarity index 100% rename from gix-fs/tests/dir/remove.rs rename to gix-fs/tests/fs/dir/remove.rs diff --git a/gix-fs/tests/fs.rs b/gix-fs/tests/fs/main.rs similarity index 91% rename from gix-fs/tests/fs.rs rename to gix-fs/tests/fs/main.rs index 5a687b5938e..0ce45f84f7a 100644 --- a/gix-fs/tests/fs.rs +++ b/gix-fs/tests/fs/main.rs @@ -3,4 +3,5 @@ type Result = std::result::Result Result<(), Box> { + let tmp = tempfile::tempdir().unwrap(); + if !has_nanosecond_times(tmp.path())? { + return Ok(()); + } + + let file_path = tmp.path().join("content"); + let smut = SharedFileSnapshotMut::::new(); + + let check = || file_path.metadata().ok()?.modified().ok(); + let open = || { + Ok(match std::fs::read_to_string(&file_path) { + Ok(s) => Some(s), + Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, + Err(err) => return Err(err), + }) + }; + let snap = smut.recent_snapshot(check, open)?; + assert!(snap.is_none()); + + std::fs::write(&file_path, "content")?; + let snap = smut.recent_snapshot(check, open)?.expect("content read"); + assert_eq!(&**snap, "content", "it read the file for the first time"); + + std::fs::write(&file_path, "change")?; + let snap = smut.recent_snapshot(check, open)?.expect("content read"); + assert_eq!(&**snap, "change", "it picks up the change"); + + std::fs::remove_file(&file_path)?; + let snap = smut.recent_snapshot(check, open)?; + assert!(snap.is_none(), "file deleted, nothing to see here"); + + std::fs::write(&file_path, "new")?; + let snap = smut.recent_snapshot(check, open)?.expect("content read again"); + let owned: String = snap.into_owned_or_cloned(); + assert_eq!(owned, "new", "owned versions are possible easily and efficiently"); + Ok(()) +} + +fn has_nanosecond_times(root: &Path) -> std::io::Result { + let test_file = root.join("nanosecond-test"); + + std::fs::write(&test_file, "a")?; + let first_time = test_file.metadata()?.modified()?; + + std::fs::write(&test_file, "b")?; + let second_time = test_file.metadata()?.modified()?; + + Ok(first_time != second_time) +} diff --git a/gix-fs/tests/stack/mod.rs b/gix-fs/tests/fs/stack.rs similarity index 100% rename from gix-fs/tests/stack/mod.rs rename to gix-fs/tests/fs/stack.rs diff --git a/gix-status/src/lib.rs b/gix-status/src/lib.rs index 6e0ed72befe..7b809fbe54a 100644 --- a/gix-status/src/lib.rs +++ b/gix-status/src/lib.rs @@ -47,7 +47,8 @@ pub use index_as_worktree_with_renames::function::index_as_worktree_with_renames /// It can efficiently validate paths when these are queried in sort-order, which leads to each component /// to only be checked once. pub struct SymlinkCheck { - inner: gix_fs::Stack, + /// Supports querying additional information, like the stack root. + pub inner: gix_fs::Stack, } mod stack; diff --git a/gix/examples/clone.rs b/gix/examples/clone.rs index b4c8d51ec31..356863c784f 100644 --- a/gix/examples/clone.rs +++ b/gix/examples/clone.rs @@ -27,11 +27,11 @@ fn main() -> anyhow::Result<()> { println!( "Checking out into {:?} ...", - prepare_checkout.repo().work_dir().expect("should be there") + prepare_checkout.repo().workdir().expect("should be there") ); let (repo, _) = prepare_checkout.main_worktree(gix::progress::Discard, &gix::interrupt::IS_INTERRUPTED)?; - println!("Repo cloned into {:?}", repo.work_dir().expect("directory pre-created")); + println!("Repo cloned into {:?}", repo.workdir().expect("directory pre-created")); let remote = repo .find_default_remote(gix::remote::Direction::Fetch) diff --git a/gix/examples/stats.rs b/gix/examples/stats.rs index 7c3680a5949..c6f06cdd571 100644 --- a/gix/examples/stats.rs +++ b/gix/examples/stats.rs @@ -4,7 +4,7 @@ use gix::{prelude::ObjectIdExt, Reference}; fn main() -> Result<(), Box> { let mut repo = gix::discover(".")?; - println!("Repo: {}", repo.work_dir().unwrap_or_else(|| repo.git_dir()).display()); + println!("Repo: {}", repo.workdir().unwrap_or_else(|| repo.git_dir()).display()); let mut max_parents = 0; let mut avg_parents = 0; repo.object_cache_size(32 * 1024); diff --git a/gix/src/clone/access.rs b/gix/src/clone/access.rs index ceada84472b..f42c3dff336 100644 --- a/gix/src/clone/access.rs +++ b/gix/src/clone/access.rs @@ -68,7 +68,7 @@ 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(); + std::fs::remove_dir_all(repo.workdir().unwrap_or_else(|| repo.path())).ok(); } } } diff --git a/gix/src/clone/checkout.rs b/gix/src/clone/checkout.rs index f2b3cd11251..920550168ff 100644 --- a/gix/src/clone/checkout.rs +++ b/gix/src/clone/checkout.rs @@ -92,7 +92,7 @@ pub mod main_worktree { .repo .as_ref() .expect("BUG: this method may only be called until it is successful"); - let workdir = repo.work_dir().ok_or_else(|| Error::BareRepository { + let workdir = repo.workdir().ok_or_else(|| Error::BareRepository { git_dir: repo.git_dir().to_owned(), })?; @@ -118,9 +118,7 @@ pub mod main_worktree { })?; let mut index = gix_index::File::from_state(index, repo.index_path()); - let mut opts = repo - .config - .checkout_options(repo, gix_worktree::stack::state::attributes::Source::IdMapping)?; + let mut opts = repo.checkout_options(gix_worktree::stack::state::attributes::Source::IdMapping)?; opts.destination_is_initially_empty = true; let mut files = progress.add_child_with_id("checkout".to_string(), ProgressId::CheckoutFiles.into()); @@ -173,7 +171,7 @@ 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(); + std::fs::remove_dir_all(repo.workdir().unwrap_or_else(|| repo.path())).ok(); } } } diff --git a/gix/src/config/cache/init.rs b/gix/src/config/cache/init.rs index d5e8fb737e4..eca58a5cacf 100644 --- a/gix/src/config/cache/init.rs +++ b/gix/src/config/cache/init.rs @@ -303,7 +303,7 @@ impl crate::Repository { } fn apply_changed_values(&mut self) { - self.refs.write_reflog = util::reflog_or_default(self.config.reflog, self.work_dir().is_some()); + self.refs.write_reflog = util::reflog_or_default(self.config.reflog, self.workdir().is_some()); self.refs.namespace.clone_from(&self.config.refs_namespace); } } diff --git a/gix/src/dirwalk/iter.rs b/gix/src/dirwalk/iter.rs index 0f31dd30b72..9bbe2449651 100644 --- a/gix/src/dirwalk/iter.rs +++ b/gix/src/dirwalk/iter.rs @@ -34,7 +34,7 @@ pub struct Outcome { /// The pathspecs used to guide the operation, pub pathspec: PathspecDetached, /// The root actually being used for the traversal, and useful to transform the paths returned for the user. - /// It's always within the [`work-dir`](Repository::work_dir). + /// It's always within the [`work-dir`](Repository::workdir). pub traversal_root: PathBuf, /// The actual result of the dirwalk. pub dirwalk: gix_dir::walk::Outcome, diff --git a/gix/src/dirwalk/mod.rs b/gix/src/dirwalk/mod.rs index 56a1612b23f..83009d3f711 100644 --- a/gix/src/dirwalk/mod.rs +++ b/gix/src/dirwalk/mod.rs @@ -64,7 +64,7 @@ pub struct Outcome<'repo> { /// The pathspecs used to guide the operation, pub pathspec: Pathspec<'repo>, /// The root actually being used for the traversal, and useful to transform the paths returned for the user. - /// It's always within the [`work-dir`](crate::Repository::work_dir). + /// It's always within the [`work-dir`](crate::Repository::workdir). pub traversal_root: PathBuf, /// The actual result of the dirwalk. pub dirwalk: gix_dir::walk::Outcome, diff --git a/gix/src/filter.rs b/gix/src/filter.rs index 73917ac93a9..4665044414d 100644 --- a/gix/src/filter.rs +++ b/gix/src/filter.rs @@ -228,7 +228,7 @@ impl Pipeline<'_> { let rela_path_as_path = gix_path::from_bstr(rela_path); let repo = self.repo; - let worktree_dir = repo.work_dir().ok_or(Error::MissingWorktree)?; + let worktree_dir = repo.workdir().ok_or(Error::MissingWorktree)?; let path = worktree_dir.join(&rela_path_as_path); let md = match std::fs::symlink_metadata(&path) { Ok(md) => md, diff --git a/gix/src/pathspec.rs b/gix/src/pathspec.rs index 9b95d1e57e0..0c14bf95ebd 100644 --- a/gix/src/pathspec.rs +++ b/gix/src/pathspec.rs @@ -60,7 +60,7 @@ impl<'repo> Pathspec<'repo> { patterns, prefix, &gix_path::realpath_opts( - repo.work_dir().unwrap_or_else(|| repo.git_dir()), + repo.workdir().unwrap_or_else(|| repo.git_dir()), repo.options.current_dir_or_empty(), gix_path::realpath::MAX_SYMLINKS, )?, diff --git a/gix/src/remote/connection/fetch/update_refs/mod.rs b/gix/src/remote/connection/fetch/update_refs/mod.rs index a692249f2a8..121f9726ad0 100644 --- a/gix/src/remote/connection/fetch/update_refs/mod.rs +++ b/gix/src/remote/connection/fetch/update_refs/mod.rs @@ -444,7 +444,7 @@ fn insert_head( head: Option>, out: &mut BTreeMap>, ) -> Result<(), update::Error> { - if let Some((head, wd)) = head.and_then(|head| head.repo.work_dir().map(|wd| (head, wd))) { + if let Some((head, wd)) = head.and_then(|head| head.repo.workdir().map(|wd| (head, wd))) { out.entry("HEAD".try_into().expect("valid")) .or_default() .push(wd.to_owned()); diff --git a/gix/src/remote/connection/fetch/update_refs/tests.rs b/gix/src/remote/connection/fetch/update_refs/tests.rs index f5e2e71dad4..b2fd25d0934 100644 --- a/gix/src/remote/connection/fetch/update_refs/tests.rs +++ b/gix/src/remote/connection/fetch/update_refs/tests.rs @@ -126,7 +126,7 @@ mod update { ( "+refs/remotes/origin/g:refs/heads/main", fetch::refs::update::Mode::RejectedCurrentlyCheckedOut { - worktree_dirs: vec![repo.work_dir().expect("present").to_owned()], + worktree_dirs: vec![repo.workdir().expect("present").to_owned()], }, None, "checked out branches cannot be written, as it requires a merge of sorts which isn't done here", @@ -498,7 +498,7 @@ mod update { "refs/heads/main", fetch::refs::Update { mode: fetch::refs::update::Mode::RejectedCurrentlyCheckedOut { - worktree_dirs: vec![repo.work_dir().expect("present").to_owned()], + worktree_dirs: vec![repo.workdir().expect("present").to_owned()], }, type_change: None, edit_index: None, diff --git a/gix/src/repository/attributes.rs b/gix/src/repository/attributes.rs index 55e28e3ff49..bf3795513a3 100644 --- a/gix/src/repository/attributes.rs +++ b/gix/src/repository/attributes.rs @@ -50,7 +50,7 @@ impl Repository { Ok(AttributeStack::new( gix_worktree::Stack::new( // this is alright as we don't cause mutation of that directory, it's virtual. - self.work_dir().unwrap_or(self.git_dir()), + self.workdir().unwrap_or(self.git_dir()), state, case, buf, @@ -82,7 +82,7 @@ impl Repository { Ok(AttributeStack::new( gix_worktree::Stack::new( // this is alright as we don't cause mutation of that directory, it's virtual. - self.work_dir().unwrap_or(self.git_dir()), + self.workdir().unwrap_or(self.git_dir()), state, case, buf, @@ -127,7 +127,7 @@ impl Repository { Ok(AttributeStack::new( gix_worktree::Stack::new( // this is alright as we don't cause mutation of that directory, it's virtual. - self.work_dir().unwrap_or(self.git_dir()), + self.workdir().unwrap_or(self.git_dir()), state, case, buf, diff --git a/gix/src/repository/checkout.rs b/gix/src/repository/checkout.rs new file mode 100644 index 00000000000..288c89804df --- /dev/null +++ b/gix/src/repository/checkout.rs @@ -0,0 +1,14 @@ +use crate::{config, Repository}; + +impl Repository { + /// Return options that can be used to drive a low-level checkout operation. + /// Use `attributes_source` to determine where `.gitattributes` files should be read from, which depends on + /// the presence of a worktree to begin with. + /// Here, typically this value would be [`gix_worktree::stack::state::attributes::Source::IdMapping`] + pub fn checkout_options( + &self, + attributes_source: gix_worktree::stack::state::attributes::Source, + ) -> Result { + self.config.checkout_options(self, attributes_source) + } +} diff --git a/gix/src/repository/config/mod.rs b/gix/src/repository/config/mod.rs index c89be929691..1658a59a125 100644 --- a/gix/src/repository/config/mod.rs +++ b/gix/src/repository/config/mod.rs @@ -107,7 +107,7 @@ impl crate::Repository { .into() }, git_dir: self.git_dir().to_owned().into(), - worktree_dir: self.work_dir().map(ToOwned::to_owned), + worktree_dir: self.workdir().map(ToOwned::to_owned), no_replace_objects: config::shared::is_replace_refs_enabled( &self.config.resolved, self.config.lenient_config, diff --git a/gix/src/repository/dirwalk.rs b/gix/src/repository/dirwalk.rs index cf7e036e7e8..2eee2a99816 100644 --- a/gix/src/repository/dirwalk.rs +++ b/gix/src/repository/dirwalk.rs @@ -36,7 +36,7 @@ impl Repository { delegate: &mut dyn gix_dir::walk::Delegate, ) -> Result, dirwalk::Error> { let _span = gix_trace::coarse!("gix::dirwalk"); - let workdir = self.work_dir().ok_or(dirwalk::Error::MissingWorkDir)?; + let workdir = self.workdir().ok_or(dirwalk::Error::MissingWorkDir)?; let mut excludes = self.excludes( index, None, @@ -56,7 +56,7 @@ impl Repository { let accelerate_lookup = fs_caps.ignore_case.then(|| index.prepare_icase_backing()); let mut opts = gix_dir::walk::Options::from(options); let worktree_relative_worktree_dirs_storage; - if let Some(workdir) = self.work_dir().filter(|_| opts.for_deletion.is_some()) { + if let Some(workdir) = self.workdir().filter(|_| opts.for_deletion.is_some()) { let linked_worktrees = self.worktrees()?; if !linked_worktrees.is_empty() { let real_workdir = gix_path::realpath_opts( diff --git a/gix/src/repository/impls.rs b/gix/src/repository/impls.rs index cbf0d64ef61..31c149c9494 100644 --- a/gix/src/repository/impls.rs +++ b/gix/src/repository/impls.rs @@ -31,7 +31,7 @@ impl std::fmt::Debug for crate::Repository { f.debug_struct("Repository") .field("kind", &self.kind()) .field("git_dir", &self.git_dir()) - .field("work_dir", &self.work_dir()) + .field("workdir", &self.workdir()) .finish() } } diff --git a/gix/src/repository/location.rs b/gix/src/repository/location.rs index 0c23b458d78..95cda2e4fc9 100644 --- a/gix/src/repository/location.rs +++ b/gix/src/repository/location.rs @@ -1,5 +1,6 @@ use std::path::{Path, PathBuf}; +use crate::bstr::BStr; use gix_path::realpath::MAX_SYMLINKS; impl crate::Repository { @@ -39,7 +40,7 @@ impl crate::Repository { /// The path to the `.gitmodules` file in the worktree, if a worktree is available. #[cfg(feature = "attributes")] pub fn modules_path(&self) -> Option { - self.work_dir().map(|wtd| wtd.join(crate::submodule::MODULES_FILE)) + self.workdir().map(|wtd| wtd.join(crate::submodule::MODULES_FILE)) } /// The path to the `.git` directory itself, or equivalent if this is a bare repository. @@ -48,11 +49,27 @@ impl crate::Repository { } /// Return the work tree containing all checked out files, if there is one. + #[deprecated = "Use `workdir()` instead"] #[doc(alias = "workdir", alias = "git2")] pub fn work_dir(&self) -> Option<&std::path::Path> { self.work_tree.as_deref() } + /// Return the work tree containing all checked out files, if there is one. + pub fn workdir(&self) -> Option<&std::path::Path> { + self.work_tree.as_deref() + } + + /// Turn `rela_path` into a path qualified with the [`workdir()`](Self::workdir()) of this instance, + /// if one is available. + pub fn workdir_path(&self, rela_path: impl AsRef) -> Option { + self.workdir().and_then(|wd| { + gix_path::try_from_bstr(rela_path.as_ref()) + .ok() + .map(|rela| wd.join(rela)) + }) + } + // TODO: tests, respect precomposeUnicode /// The directory of the binary path of the current process. pub fn install_dir(&self) -> std::io::Result { @@ -65,7 +82,7 @@ impl crate::Repository { /// Note that the CWD is obtained once upon instantiation of the repository. // TODO: tests, details - there is a lot about environment variables to change things around. pub fn prefix(&self) -> Result, gix_path::realpath::Error> { - let (root, current_dir) = match self.work_dir().zip(self.options.current_dir.as_deref()) { + let (root, current_dir) = match self.workdir().zip(self.options.current_dir.as_deref()) { Some((work_dir, cwd)) => (work_dir, cwd), None => return Ok(None), }; diff --git a/gix/src/repository/mailmap.rs b/gix/src/repository/mailmap.rs index d19d567adeb..9be9345ac65 100644 --- a/gix/src/repository/mailmap.rs +++ b/gix/src/repository/mailmap.rs @@ -33,7 +33,7 @@ impl crate::Repository { .map(Id::detach) .ok() }); - match self.work_dir() { + match self.workdir() { None => { blob_id = blob_id.or_else(|| { self.head().ok().and_then(|mut head| { diff --git a/gix/src/repository/mod.rs b/gix/src/repository/mod.rs index 20e2fa4d8c7..caa98f1613e 100644 --- a/gix/src/repository/mod.rs +++ b/gix/src/repository/mod.rs @@ -20,7 +20,10 @@ pub enum Kind { #[cfg(any(feature = "attributes", feature = "excludes"))] pub mod attributes; mod cache; +#[cfg(feature = "worktree-mutation")] +mod checkout; mod config; + /// #[cfg(feature = "blob-diff")] mod diff; diff --git a/gix/src/repository/reference.rs b/gix/src/repository/reference.rs index 6a934481ee9..e0c2366f390 100644 --- a/gix/src/repository/reference.rs +++ b/gix/src/repository/reference.rs @@ -227,6 +227,22 @@ impl crate::Repository { Ok(self.head_commit()?.tree_id()?) } + /// Like [`Self::head_tree_id()`], but will return an empty tree hash if the repository HEAD is unborn. + pub fn head_tree_id_or_empty(&self) -> Result, reference::head_tree_id::Error> { + self.head_tree_id().or_else(|err| { + if let reference::head_tree_id::Error::HeadCommit(reference::head_commit::Error::PeelToCommit( + crate::head::peel::to_commit::Error::PeelToObject(crate::head::peel::to_object::Error::Unborn { + .. + }), + )) = err + { + Ok(self.empty_tree().id()) + } else { + Err(err) + } + }) + } + /// Return the tree object the `HEAD^{tree}` reference currently points to after peeling it fully, /// following symbolic references and tags until a tree is found. /// diff --git a/gix/src/repository/worktree.rs b/gix/src/repository/worktree.rs index 16c6686d317..ae705bf1b57 100644 --- a/gix/src/repository/worktree.rs +++ b/gix/src/repository/worktree.rs @@ -45,7 +45,7 @@ impl crate::Repository { /// registered worktree in the current working dir, even if no `.git` file or directory exists. /// It's merely based on configuration, see [Worktree::dot_git_exists()] for a way to perform more validation. pub fn worktree(&self) -> Option> { - self.work_dir().map(|path| Worktree { parent: self, path }) + self.workdir().map(|path| Worktree { parent: self, path }) } /// Return true if this repository is bare, and has no main work tree. @@ -53,7 +53,7 @@ impl crate::Repository { /// This is not to be confused with the [`worktree()`][crate::Repository::worktree()] worktree, which may exists if this instance /// was opened in a worktree that was created separately. pub fn is_bare(&self) -> bool { - self.config.is_bare && self.work_dir().is_none() + self.config.is_bare && self.workdir().is_none() } /// If `id` points to a tree, produce a stream that yields one worktree entry after the other. The index of the tree at `id` diff --git a/gix/src/revision/spec/parse/delegate/navigate.rs b/gix/src/revision/spec/parse/delegate/navigate.rs index d6d70a7e1ee..efe86447746 100644 --- a/gix/src/revision/spec/parse/delegate/navigate.rs +++ b/gix/src/revision/spec/parse/delegate/navigate.rs @@ -334,7 +334,7 @@ impl delegate::Navigate for Delegate<'_> { .find_map(|stage| index.entry_index_by_path_and_stage(path, *stage).map(|_| *stage)); let exists = self .repo - .work_dir() + .workdir() .is_some_and(|root| root.join(gix_path::from_bstr(path)).exists()); self.err.push(Error::IndexLookup { desired_path: path.into(), diff --git a/gix/src/status/index_worktree.rs b/gix/src/status/index_worktree.rs index 2a98ed53631..be64f74e668 100644 --- a/gix/src/status/index_worktree.rs +++ b/gix/src/status/index_worktree.rs @@ -103,7 +103,7 @@ impl Repository { E: std::error::Error + Send + Sync + 'static, { let _span = gix_trace::coarse!("gix::index_worktree_status"); - let workdir = self.work_dir().ok_or(Error::MissingWorkDir)?; + let workdir = self.workdir().ok_or(Error::MissingWorkDir)?; let attrs_and_excludes = self.attributes( index, crate::worktree::stack::state::attributes::Source::WorktreeThenIdMapping, diff --git a/gix/src/status/iter/mod.rs b/gix/src/status/iter/mod.rs index 5b6ad9e4e19..adadc1aa69f 100644 --- a/gix/src/status/iter/mod.rs +++ b/gix/src/status/iter/mod.rs @@ -45,17 +45,7 @@ where let obtain_tree_id = || -> Result, crate::status::into_iter::Error> { Ok(match self.head_tree { - Some(None) => match self.repo.head_tree_id() { - Ok(id) => Some(id.into()), - Err(crate::reference::head_tree_id::Error::HeadCommit( - crate::reference::head_commit::Error::PeelToCommit( - crate::head::peel::to_commit::Error::PeelToObject( - crate::head::peel::to_object::Error::Unborn { .. }, - ), - ), - )) => Some(gix_hash::ObjectId::empty_tree(self.repo.object_hash())), - Err(err) => return Err(err.into()), - }, + Some(None) => Some(self.repo.head_tree_id_or_empty()?.into()), Some(Some(tree_id)) => Some(tree_id), None => None, }) diff --git a/gix/src/submodule/mod.rs b/gix/src/submodule/mod.rs index 64921d6deac..5b86ea2ad45 100644 --- a/gix/src/submodule/mod.rs +++ b/gix/src/submodule/mod.rs @@ -209,7 +209,7 @@ impl Submodule<'_> { /// doesn't have a working dir set. pub fn work_dir(&self) -> Result { let worktree_git = gix_path::from_bstr(self.path()?); - Ok(match self.state.repo.work_dir() { + Ok(match self.state.repo.workdir() { None => worktree_git.into_owned(), Some(prefix) => prefix.join(worktree_git), }) diff --git a/gix/tests/gix/clone.rs b/gix/tests/gix/clone.rs index 11d6ad3fe65..e3ab68ffc19 100644 --- a/gix/tests/gix/clone.rs +++ b/gix/tests/gix/clone.rs @@ -503,7 +503,7 @@ mod blocking_io { let index = repo.index()?; assert_eq!(index.entries().len(), 1, "All entries are known as per HEAD tree"); - assure_index_entries_on_disk(&index, repo.work_dir().expect("non-bare")); + assure_index_entries_on_disk(&index, repo.workdir().expect("non-bare")); Ok(()) } #[test] @@ -550,7 +550,7 @@ mod blocking_io { let index = repo.index()?; assert_eq!(index.entries().len(), 1, "All entries are known as per HEAD tree"); - assure_index_entries_on_disk(&index, repo.work_dir().expect("non-bare")); + assure_index_entries_on_disk(&index, repo.workdir().expect("non-bare")); Ok(()) } @@ -667,6 +667,7 @@ mod blocking_io { assert!(!repo.index_path().is_file(), "newly initialized repos have no index"); let head = repo.head()?; assert!(head.is_unborn()); + assert_eq!(repo.head_tree_id_or_empty()?, repo.empty_tree().id()); assert!( head.log_iter().all()?.is_none(), diff --git a/gix/tests/gix/head.rs b/gix/tests/gix/head.rs index 69ead585ffc..0744e6ff1c7 100644 --- a/gix/tests/gix/head.rs +++ b/gix/tests/gix/head.rs @@ -12,6 +12,7 @@ mod peel { let commit = repo.head_commit()?; assert_eq!(commit.id, expected_commit); assert_eq!(repo.head_tree_id()?, commit.tree_id()?); + assert_eq!(repo.head_tree_id_or_empty()?, commit.tree_id()?); assert_eq!(repo.head()?.try_into_peeled_id()?.expect("born"), expected_commit); assert_eq!(repo.head()?.peel_to_object_in_place()?.id, expected_commit); assert_eq!(repo.head()?.try_peel_to_id_in_place()?.expect("born"), expected_commit); diff --git a/gix/tests/gix/id.rs b/gix/tests/gix/id.rs index 397d41c9cc1..bedcd6ea946 100644 --- a/gix/tests/gix/id.rs +++ b/gix/tests/gix/id.rs @@ -14,7 +14,7 @@ fn hex_to_id(hex: &str) -> gix_hash::ObjectId { #[test] fn prefix() -> crate::Result { let repo = crate::repo("make_repo_with_fork_and_dates.sh")?.to_thread_local(); - let work_dir = repo.work_dir().expect("non-bare"); + let work_dir = repo.workdir().expect("non-bare"); let id = hex_to_id("288e509293165cb5630d08f4185bdf2445bf6170").attach(&repo); let prefix = id.shorten()?; assert_eq!(prefix.cmp_oid(&id), Ordering::Equal); diff --git a/gix/tests/gix/init.rs b/gix/tests/gix/init.rs index 70f00f135fc..fd71a874783 100644 --- a/gix/tests/gix/init.rs +++ b/gix/tests/gix/init.rs @@ -8,7 +8,7 @@ mod bare { let repo = gix::init_bare(&git_dir)?; assert_eq!(repo.kind(), gix::repository::Kind::Bare); assert!( - repo.work_dir().is_none(), + repo.workdir().is_none(), "a worktree isn't present in bare repositories" ); assert_eq!( @@ -26,7 +26,7 @@ mod bare { let repo = gix::init_bare(tmp.path())?; assert_eq!(repo.kind(), gix::repository::Kind::Bare); assert!( - repo.work_dir().is_none(), + repo.workdir().is_none(), "a worktree isn't present in bare repositories" ); assert_eq!( @@ -79,14 +79,14 @@ mod non_bare { let tmp = tempfile::tempdir()?; let repo = gix::init(tmp.path())?; assert_eq!(repo.kind(), gix::repository::Kind::WorkTree { is_linked: false }); - assert_eq!(repo.work_dir(), Some(tmp.path()), "there is a work tree by default"); + assert_eq!(repo.workdir(), Some(tmp.path()), "there is a work tree by default"); assert_eq!( repo.git_dir(), tmp.path().join(".git"), "there is a work tree by default" ); assert_eq!(gix::open(repo.git_dir())?, repo); - assert_eq!(gix::open(repo.work_dir().as_ref().expect("non-bare repo"))?, repo); + assert_eq!(gix::open(repo.workdir().as_ref().expect("non-bare repo"))?, repo); Ok(()) } @@ -117,7 +117,7 @@ mod non_bare { std::fs::write(tmp.path().join("existing.txt"), b"I was here before you")?; let repo = gix::init(tmp.path())?; - assert_eq!(repo.work_dir().expect("present"), tmp.path()); + assert_eq!(repo.workdir().expect("present"), tmp.path()); assert_eq!( repo.git_dir(), tmp.path().join(".git"), diff --git a/gix/tests/gix/remote/fetch.rs b/gix/tests/gix/remote/fetch.rs index 00221bf95d4..98c15b43685 100644 --- a/gix/tests/gix/remote/fetch.rs +++ b/gix/tests/gix/remote/fetch.rs @@ -243,7 +243,7 @@ mod blocking_and_async_io { ] { let (mut client_repo, _tmp) = { let client_repo = remote::repo("multi_round/client"); - let daemon = spawn_git_daemon_if_async(client_repo.work_dir().expect("non-bare"))?; + let daemon = spawn_git_daemon_if_async(client_repo.workdir().expect("non-bare"))?; let tmp = TempDir::new()?; let repo = gix::prepare_clone_bare( daemon.as_ref().map_or_else( @@ -270,9 +270,9 @@ mod blocking_and_async_io { )?; } let server_repo = remote::repo("multi_round/server"); - let daemon = spawn_git_daemon_if_async(server_repo.work_dir().expect("non-bare"))?; + let daemon = spawn_git_daemon_if_async(server_repo.workdir().expect("non-bare"))?; let remote = into_daemon_remote_if_async( - client_repo.remote_at(server_repo.work_dir().expect("non-bare"))?, + client_repo.remote_at(server_repo.workdir().expect("non-bare"))?, daemon.as_ref(), None, ); @@ -433,7 +433,7 @@ mod blocking_and_async_io { }, )?; let daemon = spawn_git_daemon_if_async( - repo.work_dir() + repo.workdir() .expect("non-bare") .ancestors() .nth(1) diff --git a/gix/tests/gix/repository/config/identity.rs b/gix/tests/gix/repository/config/identity.rs index 4db71402619..811a8491bf6 100644 --- a/gix/tests/gix/repository/config/identity.rs +++ b/gix/tests/gix/repository/config/identity.rs @@ -25,7 +25,7 @@ fn author_included_by_hasconfig() -> crate::Result { fn author_and_committer_and_fallback() -> crate::Result { for trust in [gix_sec::Trust::Full, gix_sec::Trust::Reduced] { let repo = named_repo("make_config_repo.sh")?; - let work_dir = repo.work_dir().expect("present").canonicalize()?; + let work_dir = repo.workdir().expect("present").canonicalize()?; let _env = Env::new() .set( "GIT_CONFIG_SYSTEM", @@ -140,7 +140,7 @@ fn author_and_committer_and_fallback() -> crate::Result { #[serial] fn author_from_different_config_sections() -> crate::Result { let repo = named_repo("make_signatures_repo.sh")?; - let work_dir = repo.work_dir().unwrap().canonicalize()?; + let work_dir = repo.workdir().unwrap().canonicalize()?; let _env = Env::new() .set("GIT_CONFIG_GLOBAL", work_dir.join("global.config").to_str().unwrap()) diff --git a/gix/tests/gix/repository/filter.rs b/gix/tests/gix/repository/filter.rs index ab7ec75198a..d90c470297d 100644 --- a/gix/tests/gix/repository/filter.rs +++ b/gix/tests/gix/repository/filter.rs @@ -35,7 +35,7 @@ fn pipeline_in_repo_without_special_options() -> crate::Result { #[cfg(unix)] fn pipeline_worktree_file_to_object() -> crate::Result { let repo = named_repo("repo_with_untracked_files.sh")?; - let work_dir = repo.work_dir().expect("non-bare"); + let work_dir = repo.workdir().expect("non-bare"); let (mut pipe, index) = repo.filter_pipeline(None)?; fn take_two(t: Option<(A, B, C)>) -> Option<(A, B)> { t.map(|t| (t.0, t.1)) diff --git a/gix/tests/gix/repository/open.rs b/gix/tests/gix/repository/open.rs index c70d0cc83ce..f24edc68914 100644 --- a/gix/tests/gix/repository/open.rs +++ b/gix/tests/gix/repository/open.rs @@ -1,8 +1,8 @@ +use crate::util::named_subrepo_opts; +use gix::bstr::BString; use std::borrow::Cow; use std::error::Error; -use crate::util::named_subrepo_opts; - #[test] fn on_root_with_decomposed_unicode() -> crate::Result { let tmp = gix_testtools::tempfile::TempDir::new()?; @@ -19,7 +19,7 @@ fn on_root_with_decomposed_unicode() -> crate::Result { .expect("created by init based on fs-capabilities"); assert!(repo.git_dir().is_dir()); - let work_dir = repo.work_dir().expect("non-bare"); + let work_dir = repo.workdir().expect("non-bare"); assert!(work_dir.is_dir()); if precompose_unicode { @@ -47,6 +47,10 @@ fn on_root_with_decomposed_unicode() -> crate::Result { Cow::Owned(_), )); } + assert!( + repo.workdir_path("").expect("non-bare").is_dir(), + "decomposed or not, we generate a valid path given what Git would store" + ); Ok(()) } @@ -62,7 +66,7 @@ fn bare_repo_with_index() -> crate::Result { repo.is_bare(), "it's properly classified as it reads the configuration (and has no worktree)" ); - assert_eq!(repo.work_dir(), None); + assert_eq!(repo.workdir(), None); Ok(()) } @@ -77,7 +81,7 @@ fn non_bare_turned_bare() -> crate::Result { repo.is_bare(), "the configuration dictates this, even though it looks like a main worktree" ); - assert_eq!(repo.work_dir(), None); + assert_eq!(repo.workdir(), None); Ok(()) } @@ -90,7 +94,7 @@ fn worktree_of_bare_repo() -> crate::Result { )?; assert!(!repo.is_bare(), "even though the main worktree is bare, this isn't"); assert_ne!( - repo.work_dir(), + repo.workdir(), None, "we have opened the repo through a worktree, which is never bare" ); @@ -105,7 +109,7 @@ fn non_bare_non_git_repo_without_worktree() -> crate::Result { gix::open::Options::isolated(), )?; assert!(!repo.is_bare()); - assert_eq!(repo.work_dir(), None, "it doesn't assume that workdir exists"); + assert_eq!(repo.workdir(), None, "it doesn't assume that workdir exists"); let repo = gix::open_opts( repo.git_dir().join("objects").join(".."), @@ -113,7 +117,7 @@ fn non_bare_non_git_repo_without_worktree() -> crate::Result { )?; assert!(!repo.is_bare()); assert_eq!( - repo.work_dir(), + repo.workdir(), None, "it figures this out even if a non-normalized gitdir is used" ); @@ -129,6 +133,20 @@ fn none_bare_repo_without_index() -> crate::Result { )?; assert!(!repo.is_bare(), "worktree isn't dependent on an index file"); assert!(repo.worktree().is_some()); + assert_eq!( + repo.workdir_path(BString::from("this")).map(|p| p.is_file()), + Some(true) + ); + #[allow(clippy::needless_borrows_for_generic_args)] + let actual = repo.workdir_path(&BString::from("this")).map(|p| p.is_file()); + assert_eq!(actual, Some(true)); + assert!( + repo.workdir_path("this") + .expect("non-bare") + .strip_prefix(repo.workdir().expect("non-bare")) + .is_ok(), + "this is a minimal path" + ); Ok(()) } @@ -146,7 +164,7 @@ fn non_bare_split_worktree() -> crate::Result { "worktree is actually configured, and it's non-bare by configuration" ); assert_eq!( - repo.work_dir().expect("worktree is configured").is_dir(), + repo.workdir().expect("worktree is configured").is_dir(), worktree_exists ); } @@ -196,7 +214,7 @@ mod missing_config_file { repo.is_bare(), "without config, we can't really know what the repo is actually but can guess by not having a worktree" ); - assert_eq!(repo.work_dir(), None); + assert_eq!(repo.workdir(), None); assert!(repo.worktree().is_none()); assert_eq!( repo.config_snapshot().meta().source, @@ -217,7 +235,7 @@ mod missing_config_file { !repo.is_bare(), "without config, we can't really know what the repo is actually but can guess as there is a worktree" ); - assert!(repo.work_dir().is_some()); + assert!(repo.workdir().is_some()); assert!(repo.worktree().is_some()); assert_eq!( repo.config_snapshot().meta().source, @@ -289,12 +307,12 @@ mod submodules { ] { let repo = discover_repo(discover_dir).unwrap(); // assert_eq!(repo.kind(), gix::Kind::Submodule); - assert_eq!(repo.work_dir().expect("non-bare"), dir.join(&submodule_m1_workdir)); + assert_eq!(repo.workdir().expect("non-bare"), dir.join(&submodule_m1_workdir)); assert_eq!(repo.git_dir(), dir.join(&submodule_m1_gitdir)); - let repo = gix::open_opts(repo.work_dir().expect("non-bare"), gix::open::Options::isolated()).unwrap(); + let repo = gix::open_opts(repo.workdir().expect("non-bare"), gix::open::Options::isolated()).unwrap(); assert_eq!(repo.kind(), gix::repository::Kind::Submodule); - assert_eq!(repo.work_dir().expect("non-bare"), dir.join(&submodule_m1_workdir)); + assert_eq!(repo.workdir().expect("non-bare"), dir.join(&submodule_m1_workdir)); assert_eq!(repo.git_dir(), dir.join(&submodule_m1_gitdir)); } } @@ -358,7 +376,7 @@ mod worktree { let base_config = base.config_snapshot(); assert_eq!( - base.work_dir(), + base.workdir(), Some(fixture_dir.join("repo").as_path()), "the main worktree" ); @@ -387,7 +405,7 @@ mod worktree { let wt1 = open(fixture_dir.join("wt-1"))?; let wt1_config = wt1.config_snapshot(); assert_eq!( - wt1.work_dir(), + wt1.workdir(), Some(fixture_dir.join("wt-1").as_path()), "a linked worktree in its own location" ); @@ -420,7 +438,7 @@ mod worktree { let wt2 = open(fixture_dir.join("wt-2"))?; let wt2_config = wt2.config_snapshot(); assert_eq!( - wt2.work_dir(), + wt2.workdir(), Some(fixture_dir.join("wt-2").as_path()), "another linked worktree as sibling to wt-1" ); diff --git a/gix/tests/gix/repository/pathspec.rs b/gix/tests/gix/repository/pathspec.rs index d4b61235ce6..dd8b350fc2b 100644 --- a/gix/tests/gix/repository/pathspec.rs +++ b/gix/tests/gix/repository/pathspec.rs @@ -16,7 +16,7 @@ fn defaults_are_taken_from_repo_config() -> crate::Result { "hi", ":!hip", gix::path::to_unix_separators_on_windows(gix::path::into_bstr( - repo.work_dir().expect("present").join("for-normalization"), + repo.workdir().expect("present").join("for-normalization"), )) .to_str_lossy() .as_ref(), diff --git a/gix/tests/gix/repository/remote.rs b/gix/tests/gix/repository/remote.rs index b45b3ba036b..84ae6723407 100644 --- a/gix/tests/gix/repository/remote.rs +++ b/gix/tests/gix/repository/remote.rs @@ -280,7 +280,7 @@ mod find_remote { fn base_dir(repo: &Repository) -> String { gix_path::to_unix_separators_on_windows(gix::path::into_bstr( - gix::path::realpath(repo.work_dir().unwrap()) + gix::path::realpath(repo.workdir().unwrap()) .unwrap() .parent() .unwrap() diff --git a/gix/tests/gix/repository/worktree.rs b/gix/tests/gix/repository/worktree.rs index 294ab4a5bc2..ad233eff627 100644 --- a/gix/tests/gix/repository/worktree.rs +++ b/gix/tests/gix/repository/worktree.rs @@ -49,13 +49,13 @@ mod with_core_worktree_config { if is_relative { assert_eq!( - repo.work_dir().unwrap(), + repo.workdir().unwrap(), repo.git_dir().parent().unwrap().parent().unwrap().join("worktree"), "{name}|{is_relative}: work_dir is set to core.worktree config value, relative paths are appended to `git_dir() and made absolute`" ); } else { assert_eq!( - repo.work_dir().unwrap(), + repo.workdir().unwrap(), gix_path::realpath(repo.git_dir().parent().unwrap().parent().unwrap().join("worktree"))?, "absolute workdirs are left untouched" ); @@ -63,7 +63,7 @@ mod with_core_worktree_config { assert_eq!( repo.worktree().expect("present").base(), - repo.work_dir().unwrap(), + repo.workdir().unwrap(), "current worktree is based on work-tree dir" ); @@ -99,7 +99,7 @@ mod with_core_worktree_config { ); assert!( - !repo.work_dir().expect("configured").exists(), + !repo.workdir().expect("configured").exists(), "non-existing or invalid worktrees (this one is a file) are taken verbatim and \ may lead to errors later - just like in `git` and we explicitly do not try to be smart about it" ); @@ -111,7 +111,7 @@ mod with_core_worktree_config { assert_eq!(count_deleted(repo.git_dir()), 0, "git can't chdir into a file"); assert!( - repo.work_dir().expect("configured").is_file(), + repo.workdir().expect("configured").is_file(), "non-existing or invalid worktrees (this one is a file) are taken verbatim and \ may lead to errors later - just like in `git` and we explicitly do not try to be smart about it" ); @@ -128,7 +128,7 @@ mod with_core_worktree_config { "git refuses to mix bare with core.worktree" ); assert!( - repo.work_dir().is_none(), + repo.workdir().is_none(), "we simply don't load core.worktree in bare repos either to match this behaviour" ); assert!(repo.try_index()?.is_none()); @@ -258,7 +258,7 @@ fn run_assertions(main_repo: gix::Repository, should_be_bare: bool) { assert_eq!(main_repo.is_bare(), should_be_bare); let mut baseline = Baseline::collect( main_repo - .work_dir() + .workdir() .map_or_else(|| main_repo.git_dir().parent(), std::path::Path::parent) .expect("a temp dir as parent"), ) @@ -270,7 +270,7 @@ fn run_assertions(main_repo: gix::Repository, should_be_bare: bool) { assert!(main_repo.worktree().is_none()); } else { assert_eq!( - main_repo.work_dir().expect("non-bare").canonicalize().unwrap(), + main_repo.workdir().expect("non-bare").canonicalize().unwrap(), expected_main.root.canonicalize().unwrap() ); assert_eq!(main_repo.head_id().unwrap(), expected_main.peeled); diff --git a/gix/tests/gix/revision/spec/from_bytes/util.rs b/gix/tests/gix/revision/spec/from_bytes/util.rs index 0073eaf618a..76dfaee7b98 100644 --- a/gix/tests/gix/revision/spec/from_bytes/util.rs +++ b/gix/tests/gix/revision/spec/from_bytes/util.rs @@ -172,7 +172,7 @@ fn compare_with_baseline( let actual = res.as_deref().ok().copied(); let spec: BString = spec.into(); let expected = *BASELINE - .get(repo.work_dir().unwrap_or_else(|| repo.git_dir())) + .get(repo.workdir().unwrap_or_else(|| repo.git_dir())) .unwrap_or_else(|| panic!("No baseline for {repo:?}")) .get(&spec) .unwrap_or_else(|| panic!("'{spec}' revspec not found in git baseline")); diff --git a/gix/tests/gix/submodule.rs b/gix/tests/gix/submodule.rs index 8ab6fc629ae..b9de22937cd 100644 --- a/gix/tests/gix/submodule.rs +++ b/gix/tests/gix/submodule.rs @@ -83,7 +83,7 @@ mod open { gix::repository::Kind::Submodule, "Submodules are properly detected" ); - assert!(sm_repo.work_dir().is_some(), "the workdir is always configured"); + assert!(sm_repo.workdir().is_some(), "the workdir is always configured"); let worktree = sm_repo .worktree() .expect("worktrees are always returned even if there seems to not be a checkout"); @@ -349,7 +349,7 @@ mod open { "worktree-of-submodule", gix::open::Options::isolated(), )?; - let wd = sm_repo.work_dir().expect("workdir is present"); + let wd = sm_repo.workdir().expect("workdir is present"); assert!( sm_repo.rev_parse_single(":this").is_ok(), "the file is in the submodule" @@ -371,7 +371,7 @@ mod open { "submodule-with-extra-worktree-host/m1", gix::open::Options::isolated(), )?; - let wd = sm_repo.work_dir().expect("workdir is present"); + let wd = sm_repo.workdir().expect("workdir is present"); assert!( sm_repo.rev_parse_single(":this").is_ok(), "the file is in the submodule"