Skip to content

Commit 88cbf7f

Browse files
cruesslerByron
authored andcommitted
Adapt to changes in gix-path
1 parent 9f8a468 commit 88cbf7f

File tree

10 files changed

+81
-108
lines changed

10 files changed

+81
-108
lines changed

gix-negotiate/tests/baseline/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn run() -> crate::Result {
7171
// }
7272
for tip in lookup_names(&["HEAD"]).into_iter().chain(
7373
refs.iter()?
74-
.prefixed(b"refs/heads")?
74+
.prefixed(b"refs/heads".try_into().unwrap())?
7575
.filter_map(Result::ok)
7676
.map(|r| r.target.into_id()),
7777
) {

gix-ref/src/namespace.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::path::Path;
22

33
use gix_object::bstr::{BStr, BString, ByteSlice, ByteVec};
4+
use gix_path::relative_path::RelativePath;
45

56
use crate::{FullName, FullNameRef, Namespace, PartialNameRef};
67

@@ -20,9 +21,8 @@ impl Namespace {
2021
/// Append the given `prefix` to this namespace so it becomes usable for prefixed iteration.
2122
///
2223
/// The prefix is a relative path with slash-separated path components.
23-
// TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it.
24-
pub fn into_namespaced_prefix<'a>(mut self, prefix: impl Into<&'a BStr>) -> BString {
25-
self.0.push_str(prefix.into());
24+
pub fn into_namespaced_prefix(mut self, prefix: &RelativePath) -> BString {
25+
self.0.push_str(prefix);
2626
gix_path::to_unix_separators_on_windows(self.0).into_owned()
2727
}
2828
pub(crate) fn into_namespaced_name(mut self, name: &FullNameRef) -> FullName {

gix-ref/src/store/file/loose/iter.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use std::path::{Path, PathBuf};
22

33
use gix_features::fs::walkdir::DirEntryIter;
44
use gix_object::bstr::ByteSlice;
5+
use gix_path::relative_path::RelativePath;
56

6-
use crate::{file::iter::LooseThenPacked, store_impl::file, BStr, BString, FullName};
7+
use crate::{file::iter::LooseThenPacked, store_impl::file, BString, FullName};
78

89
/// An iterator over all valid loose reference paths as seen from a particular base directory.
910
pub(in crate::store_impl::file) struct SortedLoosePaths {
@@ -88,8 +89,7 @@ impl file::Store {
8889
/// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`.
8990
///
9091
/// Prefixes are relative paths with slash-separated components.
91-
// TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it.
92-
pub fn loose_iter_prefixed<'a>(&self, prefix: impl Into<&'a BStr>) -> std::io::Result<LooseThenPacked<'_, '_>> {
93-
self.iter_prefixed_packed(prefix.into(), None)
92+
pub fn loose_iter_prefixed(&self, prefix: &RelativePath) -> std::io::Result<LooseThenPacked<'_, '_>> {
93+
self.iter_prefixed_packed(prefix, None)
9494
}
9595
}

gix-ref/src/store/file/overlay_iter.rs

+12-29
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use crate::{
1212
BStr, FullName, Namespace, Reference,
1313
};
1414

15+
use gix_object::bstr::ByteSlice;
16+
use gix_path::relative_path::RelativePath;
17+
1518
/// An iterator stepping through sorted input of loose references and packed references, preferring loose refs over otherwise
1619
/// equivalent packed references.
1720
///
@@ -203,10 +206,9 @@ impl Platform<'_> {
203206
/// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`.
204207
///
205208
/// Prefixes are relative paths with slash-separated components.
206-
// TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it.
207-
pub fn prefixed<'a>(&self, prefix: impl Into<&'a BStr>) -> std::io::Result<LooseThenPacked<'_, '_>> {
209+
pub fn prefixed(&self, prefix: &RelativePath) -> std::io::Result<LooseThenPacked<'_, '_>> {
208210
self.store
209-
.iter_prefixed_packed(prefix.into(), self.packed.as_ref().map(|b| &***b))
211+
.iter_prefixed_packed(prefix, self.packed.as_ref().map(|b| &***b))
210212
}
211213
}
212214

@@ -291,26 +293,8 @@ impl<'a> IterInfo<'a> {
291293
.peekable()
292294
}
293295

294-
fn from_prefix(
295-
base: &'a Path,
296-
prefix: impl Into<Cow<'a, BStr>>,
297-
precompose_unicode: bool,
298-
) -> std::io::Result<Self> {
299-
let prefix = prefix.into();
300-
let prefix_path = gix_path::from_bstr(prefix.as_ref());
301-
if prefix_path.is_absolute() {
302-
return Err(std::io::Error::new(
303-
std::io::ErrorKind::InvalidInput,
304-
"prefix must be a relative path, like 'refs/heads/'",
305-
));
306-
}
307-
use std::path::Component::*;
308-
if prefix_path.components().any(|c| matches!(c, CurDir | ParentDir)) {
309-
return Err(std::io::Error::new(
310-
std::io::ErrorKind::InvalidInput,
311-
"Refusing to handle prefixes with relative path components",
312-
));
313-
}
296+
fn from_prefix(base: &'a Path, prefix: &'a RelativePath, precompose_unicode: bool) -> std::io::Result<Self> {
297+
let prefix_path = gix_path::from_bstr(prefix);
314298
let iter_root = base.join(&prefix_path);
315299
if prefix.ends_with(b"/") {
316300
Ok(IterInfo::BaseAndIterRoot {
@@ -326,7 +310,7 @@ impl<'a> IterInfo<'a> {
326310
.to_owned();
327311
Ok(IterInfo::ComputedIterationRoot {
328312
base,
329-
prefix,
313+
prefix: prefix.into(),
330314
iter_root,
331315
precompose_unicode,
332316
})
@@ -377,13 +361,11 @@ impl file::Store {
377361
/// starts with `foo`, like `refs/heads/foo` and `refs/heads/foobar`.
378362
///
379363
/// Prefixes are relative paths with slash-separated components.
380-
// TODO: use `RelativePath` type instead (see #1921), or a trait that helps convert into it.
381-
pub fn iter_prefixed_packed<'a, 's, 'p>(
364+
pub fn iter_prefixed_packed<'s, 'p>(
382365
&'s self,
383-
prefix: impl Into<&'a BStr>,
366+
prefix: &RelativePath,
384367
packed: Option<&'p packed::Buffer>,
385368
) -> std::io::Result<LooseThenPacked<'p, 's>> {
386-
let prefix = prefix.into();
387369
match self.namespace.as_ref() {
388370
None => {
389371
let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix, self.precompose_unicode)?;
@@ -395,7 +377,8 @@ impl file::Store {
395377
}
396378
Some(namespace) => {
397379
let prefix = namespace.to_owned().into_namespaced_prefix(prefix);
398-
let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.clone(), self.precompose_unicode)?;
380+
let prefix = prefix.as_bstr().try_into().map_err(std::io::Error::other)?;
381+
let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix, self.precompose_unicode)?;
399382
let common_dir_info = self
400383
.common_dir()
401384
.map(|base| IterInfo::from_prefix(base, prefix, self.precompose_unicode))

gix-ref/tests/refs/file/store/iter.rs

+11-41
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ mod with_namespace {
2626
let ns_two = gix_ref::namespace::expand("bar")?;
2727
let namespaced_refs = store
2828
.iter()?
29-
.prefixed(ns_two.as_bstr())?
29+
.prefixed(ns_two.as_bstr().try_into().unwrap())?
3030
.map(Result::unwrap)
3131
.map(|r: gix_ref::Reference| r.name)
3232
.collect::<Vec<_>>();
@@ -45,7 +45,7 @@ mod with_namespace {
4545
);
4646
assert_eq!(
4747
store
48-
.loose_iter_prefixed(ns_two.as_bstr())?
48+
.loose_iter_prefixed(ns_two.as_bstr().try_into().unwrap())?
4949
.map(Result::unwrap)
5050
.map(|r| r.name.into_inner())
5151
.collect::<Vec<_>>(),
@@ -90,7 +90,7 @@ mod with_namespace {
9090
assert_eq!(
9191
store
9292
.iter()?
93-
.prefixed(ns_one.as_bstr())?
93+
.prefixed(ns_one.as_bstr().try_into().unwrap())?
9494
.map(Result::unwrap)
9595
.map(|r: gix_ref::Reference| (
9696
r.name.as_bstr().to_owned(),
@@ -316,26 +316,11 @@ fn loose_iter_with_broken_refs() -> crate::Result {
316316
Ok(())
317317
}
318318

319-
#[test]
320-
fn loose_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result {
321-
let store = store()?;
322-
#[cfg(not(windows))]
323-
let abs_path = "/hello";
324-
#[cfg(windows)]
325-
let abs_path = r"c:\hello";
326-
327-
match store.loose_iter_prefixed(abs_path) {
328-
Ok(_) => unreachable!("absolute paths aren't allowed"),
329-
Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"),
330-
}
331-
Ok(())
332-
}
333-
334319
#[test]
335320
fn loose_iter_with_prefix() -> crate::Result {
336321
let prefix_with_slash = b"refs/heads/";
337322
let actual = store()?
338-
.loose_iter_prefixed(prefix_with_slash)?
323+
.loose_iter_prefixed(prefix_with_slash.try_into().unwrap())?
339324
.collect::<Result<Vec<_>, _>>()
340325
.expect("no broken ref in this subset")
341326
.into_iter()
@@ -363,7 +348,7 @@ fn loose_iter_with_prefix() -> crate::Result {
363348
fn loose_iter_with_partial_prefix_dir() -> crate::Result {
364349
let prefix_without_slash = b"refs/heads";
365350
let actual = store()?
366-
.loose_iter_prefixed(prefix_without_slash)?
351+
.loose_iter_prefixed(prefix_without_slash.try_into().unwrap())?
367352
.collect::<Result<Vec<_>, _>>()
368353
.expect("no broken ref in this subset")
369354
.into_iter()
@@ -390,7 +375,7 @@ fn loose_iter_with_partial_prefix_dir() -> crate::Result {
390375
#[test]
391376
fn loose_iter_with_partial_prefix() -> crate::Result {
392377
let actual = store()?
393-
.loose_iter_prefixed(b"refs/heads/d".as_bstr())?
378+
.loose_iter_prefixed(b"refs/heads/d".as_bstr().try_into().unwrap())?
394379
.collect::<Result<Vec<_>, _>>()
395380
.expect("no broken ref in this subset")
396381
.into_iter()
@@ -526,29 +511,14 @@ fn overlay_iter_reproduce_1928() -> crate::Result {
526511
Ok(())
527512
}
528513

529-
#[test]
530-
fn overlay_iter_with_prefix_wont_allow_absolute_paths() -> crate::Result {
531-
let store = store_with_packed_refs()?;
532-
#[cfg(not(windows))]
533-
let abs_path = "/hello";
534-
#[cfg(windows)]
535-
let abs_path = r"c:\hello";
536-
537-
match store.iter()?.prefixed(abs_path) {
538-
Ok(_) => unreachable!("absolute paths aren't allowed"),
539-
Err(err) => assert_eq!(err.to_string(), "prefix must be a relative path, like 'refs/heads/'"),
540-
}
541-
Ok(())
542-
}
543-
544514
#[test]
545515
fn overlay_prefixed_iter() -> crate::Result {
546516
use gix_ref::Target::*;
547517

548518
let store = store_at("make_packed_ref_repository_for_overlay.sh")?;
549519
let ref_names = store
550520
.iter()?
551-
.prefixed(b"refs/heads/")?
521+
.prefixed(b"refs/heads/".try_into().unwrap())?
552522
.map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target)))
553523
.collect::<Result<Vec<_>, _>>()?;
554524
let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03");
@@ -571,7 +541,7 @@ fn overlay_partial_prefix_iter() -> crate::Result {
571541
let store = store_at("make_packed_ref_repository_for_overlay.sh")?;
572542
let ref_names = store
573543
.iter()?
574-
.prefixed(b"refs/heads/m")? // 'm' is partial
544+
.prefixed(b"refs/heads/m".try_into().unwrap())? // 'm' is partial
575545
.map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target)))
576546
.collect::<Result<Vec<_>, _>>()?;
577547
let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03");
@@ -589,7 +559,7 @@ fn overlay_partial_prefix_iter_reproduce_1934() -> crate::Result {
589559

590560
let ref_names = store
591561
.iter()?
592-
.prefixed(b"refs/d")?
562+
.prefixed(b"refs/d".try_into().unwrap())?
593563
.map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target)))
594564
.collect::<Result<Vec<_>, _>>()?;
595565
assert_eq!(
@@ -610,7 +580,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result {
610580

611581
let ref_names = store
612582
.iter()?
613-
.prefixed(b"refs/prefix/feature")?
583+
.prefixed(b"refs/prefix/feature".try_into().unwrap())?
614584
.map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target)))
615585
.collect::<Result<Vec<_>, _>>()?;
616586
assert_eq!(
@@ -623,7 +593,7 @@ fn overlay_partial_prefix_iter_when_prefix_is_dir() -> crate::Result {
623593

624594
let ref_names = store
625595
.iter()?
626-
.prefixed(b"refs/prefix/feature/")?
596+
.prefixed(b"refs/prefix/feature/".try_into().unwrap())?
627597
.map(|r| r.map(|r| (r.name.as_bstr().to_owned(), r.target)))
628598
.collect::<Result<Vec<_>, _>>()?;
629599
assert_eq!(

gix-ref/tests/refs/file/worktree.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ mod writable {
290290
assert_eq!(
291291
store
292292
.iter()?
293-
.prefixed(b"refs/stacks/")?
293+
.prefixed(b"refs/stacks/".try_into().unwrap())?
294294
.map(Result::unwrap)
295295
.map(|r| (r.name.to_string(), r.target.to_string()))
296296
.collect::<Vec<_>>(),
@@ -571,7 +571,7 @@ mod writable {
571571
assert_eq!(
572572
store
573573
.iter()?
574-
.prefixed(b"refs/stacks/")?
574+
.prefixed(b"refs/stacks/".try_into().unwrap())?
575575
.map(Result::unwrap)
576576
.map(|r| (r.name.to_string(), r.target.to_string()))
577577
.collect::<Vec<_>>(),

gix-ref/tests/refs/namespace.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ fn into_namespaced_prefix() {
33
assert_eq!(
44
gix_ref::namespace::expand("foo")
55
.unwrap()
6-
.into_namespaced_prefix("prefix"),
6+
.into_namespaced_prefix("prefix".try_into().unwrap()),
77
"refs/namespaces/foo/prefix",
88
);
99
assert_eq!(
1010
gix_ref::namespace::expand("foo")
1111
.unwrap()
12-
.into_namespaced_prefix("prefix/"),
12+
.into_namespaced_prefix("prefix/".try_into().unwrap()),
1313
"refs/namespaces/foo/prefix/",
1414
);
1515
}

gix/src/open/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ pub enum Error {
5656
UnsafeGitDir { path: PathBuf },
5757
#[error(transparent)]
5858
EnvironmentAccessDenied(#[from] gix_sec::permission::Error<std::path::PathBuf>),
59+
#[error(transparent)]
60+
PrefixNotRelative(#[from] gix_path::relative_path::Error),
5961
}
6062

6163
mod options;

gix/src/open/repository.rs

+26-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![allow(clippy::result_large_err)]
22
use super::{Error, Options};
33
use crate::{
4-
bstr,
54
bstr::BString,
65
config,
76
config::{
@@ -12,6 +11,8 @@ use crate::{
1211
ThreadSafeRepository,
1312
};
1413
use gix_features::threading::OwnShared;
14+
use gix_object::bstr::ByteSlice;
15+
use gix_path::relative_path::RelativePath;
1516
use std::ffi::OsStr;
1617
use std::{borrow::Cow, path::PathBuf};
1718

@@ -345,24 +346,30 @@ impl ThreadSafeRepository {
345346

346347
refs.write_reflog = config::cache::util::reflog_or_default(config.reflog, worktree_dir.is_some());
347348
refs.namespace.clone_from(&config.refs_namespace);
348-
let replacements = replacement_objects_refs_prefix(&config.resolved, lenient_config, filter_config_section)?
349-
.and_then(|prefix| {
350-
use bstr::ByteSlice;
351-
let _span = gix_trace::detail!("find replacement objects");
352-
let platform = refs.iter().ok()?;
353-
let iter = platform.prefixed(prefix.as_bstr()).ok()?;
354-
let replacements = iter
355-
.filter_map(Result::ok)
356-
.filter_map(|r: gix_ref::Reference| {
357-
let target = r.target.try_id()?.to_owned();
358-
let source =
359-
gix_hash::ObjectId::from_hex(r.name.as_bstr().strip_prefix(prefix.as_slice())?).ok()?;
360-
Some((source, target))
361-
})
362-
.collect::<Vec<_>>();
363-
Some(replacements)
364-
})
365-
.unwrap_or_default();
349+
let prefix = replacement_objects_refs_prefix(&config.resolved, lenient_config, filter_config_section)?;
350+
let replacements = match prefix {
351+
Some(prefix) => {
352+
let prefix: &RelativePath = prefix.as_bstr().try_into()?;
353+
354+
Some(prefix).and_then(|prefix| {
355+
let _span = gix_trace::detail!("find replacement objects");
356+
let platform = refs.iter().ok()?;
357+
let iter = platform.prefixed(prefix).ok()?;
358+
let replacements = iter
359+
.filter_map(Result::ok)
360+
.filter_map(|r: gix_ref::Reference| {
361+
let target = r.target.try_id()?.to_owned();
362+
let source =
363+
gix_hash::ObjectId::from_hex(r.name.as_bstr().strip_prefix(prefix.as_ref())?).ok()?;
364+
Some((source, target))
365+
})
366+
.collect::<Vec<_>>();
367+
Some(replacements)
368+
})
369+
}
370+
None => None,
371+
};
372+
let replacements = replacements.unwrap_or_default();
366373

367374
Ok(ThreadSafeRepository {
368375
objects: OwnShared::new(gix_odb::Store::at_opts(

0 commit comments

Comments
 (0)