Skip to content

Commit 776f9be

Browse files
committed
feat: add Repository::workdir_path() to easily obtain a Path for worktree items.
1 parent abb53fb commit 776f9be

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

gix/src/repository/location.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::path::{Path, PathBuf};
22

3+
use crate::bstr::BStr;
34
use gix_path::realpath::MAX_SYMLINKS;
45

56
impl crate::Repository {
@@ -59,6 +60,16 @@ impl crate::Repository {
5960
self.work_tree.as_deref()
6061
}
6162

63+
/// Turn `rela_path` into a path qualified with the [`workdir()`](Self::workdir()) of this instance,
64+
/// if one is available.
65+
pub fn workdir_path(&self, rela_path: impl AsRef<BStr>) -> Option<PathBuf> {
66+
self.workdir().and_then(|wd| {
67+
gix_path::try_from_bstr(rela_path.as_ref())
68+
.ok()
69+
.map(|rela| wd.join(rela))
70+
})
71+
}
72+
6273
// TODO: tests, respect precomposeUnicode
6374
/// The directory of the binary path of the current process.
6475
pub fn install_dir(&self) -> std::io::Result<PathBuf> {

gix/tests/gix/repository/open.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use crate::util::named_subrepo_opts;
2+
use gix::bstr::BString;
13
use std::borrow::Cow;
24
use std::error::Error;
35

4-
use crate::util::named_subrepo_opts;
5-
66
#[test]
77
fn on_root_with_decomposed_unicode() -> crate::Result {
88
let tmp = gix_testtools::tempfile::TempDir::new()?;
@@ -47,6 +47,10 @@ fn on_root_with_decomposed_unicode() -> crate::Result {
4747
Cow::Owned(_),
4848
));
4949
}
50+
assert!(
51+
repo.workdir_path("").expect("non-bare").is_dir(),
52+
"decomposed or not, we generate a valid path given what Git would store"
53+
);
5054

5155
Ok(())
5256
}
@@ -129,6 +133,20 @@ fn none_bare_repo_without_index() -> crate::Result {
129133
)?;
130134
assert!(!repo.is_bare(), "worktree isn't dependent on an index file");
131135
assert!(repo.worktree().is_some());
136+
assert_eq!(
137+
repo.workdir_path(BString::from("this")).map(|p| p.is_file()),
138+
Some(true)
139+
);
140+
#[allow(clippy::needless_borrows_for_generic_args)]
141+
let actual = repo.workdir_path(&BString::from("this")).map(|p| p.is_file());
142+
assert_eq!(actual, Some(true));
143+
assert!(
144+
repo.workdir_path("this")
145+
.expect("non-bare")
146+
.strip_prefix(repo.workdir().expect("non-bare"))
147+
.is_ok(),
148+
"this is a minimal path"
149+
);
132150
Ok(())
133151
}
134152

0 commit comments

Comments
 (0)