Skip to content

Commit 7d8d167

Browse files
committed
use gix_fs::current_dir(precompose_unicode).
That way, paths will be precomposed when we work with them.
1 parent e7b2ac1 commit 7d8d167

File tree

16 files changed

+142
-38
lines changed

16 files changed

+142
-38
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gix-discover/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ gix-sec = { version = "^0.10.3", path = "../gix-sec" }
1717
gix-path = { version = "^0.10.3", path = "../gix-path" }
1818
gix-ref = { version = "^0.40.1", path = "../gix-ref" }
1919
gix-hash = { version = "^0.14.1", path = "../gix-hash" }
20+
gix-fs = { version = "^0.9.1", path = "../gix-fs" }
2021

2122
bstr = { version = "1.3.0", default-features = false, features = ["std", "unicode"] }
2223
thiserror = "1.0.26"

gix-discover/src/upwards/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@ pub(crate) mod function {
3939
// us the parent directory. (`Path::parent` just strips off the last
4040
// path component, which means it will not do what you expect when
4141
// working with paths paths that contain '..'.)
42-
let cwd = current_dir.map_or_else(|| std::env::current_dir().map(Cow::Owned), |cwd| Ok(Cow::Borrowed(cwd)))?;
42+
let cwd = current_dir.map_or_else(
43+
|| {
44+
// The paths we return are relevant to the repository, but at this time it's impossible to know
45+
// what `core.precomposeUnicode` is going to be. Hence the one using these paths will have to
46+
// transform the paths as needed, because we can't. `false` means to leave the obtained path as is.
47+
gix_fs::current_dir(false).map(Cow::Owned)
48+
},
49+
|cwd| Ok(Cow::Borrowed(cwd)),
50+
)?;
4351
#[cfg(windows)]
4452
let directory = dunce::simplified(directory);
4553
let dir = gix_path::normalize(directory.into(), cwd.as_ref()).ok_or_else(|| Error::InvalidInput {

gix-discover/src/upwards/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ pub struct Options<'a> {
6363
/// that this is merely an optimization for those who discover a lot of repositories in the same process.
6464
///
6565
/// If unset, the current working directory will be obtained automatically.
66+
/// Note that the path here might or might not contained decomposed unicode, which may end up in a path
67+
/// relevant us, like the git-dir or the worktree-dir. However, when opening the repository, it will
68+
/// change decomposed unicode to precomposed unicode based on the value of `core.precomposeUnicode`, and we
69+
/// don't have to deal with that value here just yet.
6670
pub current_dir: Option<&'a std::path::Path>,
6771
}
6872

gix-odb/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ gix-path = { version = "^0.10.3", path = "../gix-path" }
2525
gix-quote = { version = "^0.4.10", path = "../gix-quote" }
2626
gix-object = { version = "^0.40.1", path = "../gix-object" }
2727
gix-pack = { version = "^0.46.1", path = "../gix-pack", default-features = false }
28+
gix-fs = { version = "^0.9.1", path = "../gix-fs" }
2829
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]}
2930

3031
tempfile = "3.1.0"

gix-odb/src/store_impls/dynamic/init.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct Options {
1717
/// If false, no multi-pack indices will be used. If true, they will be used if their hash matches `object_hash`.
1818
pub use_multi_pack_index: bool,
1919
/// The current directory of the process at the time of instantiation.
20-
/// If unset, it will be retrieved using `std::env::current_dir()`.
20+
/// If unset, it will be retrieved using `gix_fs::current_dir(false)`.
2121
pub current_dir: Option<std::path::PathBuf>,
2222
}
2323

@@ -80,7 +80,13 @@ impl Store {
8080
}: Options,
8181
) -> std::io::Result<Self> {
8282
let _span = gix_features::trace::detail!("gix_odb::Store::at()");
83-
let current_dir = current_dir.map_or_else(std::env::current_dir, Ok)?;
83+
let current_dir = current_dir.map_or_else(
84+
|| {
85+
// It's only used for real-pathing alternate paths and there it just needs to be consistent (enough).
86+
gix_fs::current_dir(false)
87+
},
88+
Ok,
89+
)?;
8490
if !objects_dir.is_dir() {
8591
return Err(std::io::Error::new(
8692
std::io::ErrorKind::Other, // TODO: use NotADirectory when stabilized

gix-path/src/convert.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ pub fn to_windows_separators<'a>(path: impl Into<Cow<'a, BStr>>) -> Cow<'a, BStr
246246
/// instead.
247247
///
248248
/// Note that we might access the `current_dir` if we run out of path components to pop off, which is expected to be absolute
249-
/// as typical return value of `std::env::current_dir()`.
249+
/// as typical return value of `std::env::current_dir()` or `gix_fs::current_dir(…)` when `core.precomposeUnicode` is known.
250250
/// As a `current_dir` like `/c` can be exhausted by paths like `../../r`, `None` will be returned to indicate the inability
251251
/// to produce a logically consistent path.
252252
pub fn normalize<'a>(path: Cow<'a, Path>, current_dir: &Path) -> Option<Cow<'a, Path>> {

gix-path/src/realpath.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub(crate) mod function {
3030
/// Do not fail for non-existing components, but assume these are as is.
3131
///
3232
/// If `path` is relative, the current working directory be used to make it absolute.
33+
/// Note that the returned path will be verbatim, and repositories with `core.precomposeUnicode`
34+
/// set will probably want to precompose the paths unicode.
3335
pub fn realpath(path: impl AsRef<Path>) -> Result<PathBuf, Error> {
3436
let path = path.as_ref();
3537
let cwd = path

gix/src/config/cache/incubate.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![allow(clippy::result_large_err)]
2+
23
use super::{util, Error};
3-
use crate::config::tree::{Core, Extensions};
4+
use crate::config::cache::util::ApplyLeniency;
5+
use crate::config::tree::{Core, Extensions, Key};
46

57
/// A utility to deal with the cyclic dependency between the ref store and the configuration. The ref-store needs the
68
/// object hash kind, and the configuration needs the current branch name to resolve conditional includes with `onbranch`.
@@ -12,6 +14,7 @@ pub(crate) struct StageOne {
1214
pub lossy: Option<bool>,
1315
pub object_hash: gix_hash::Kind,
1416
pub reflog: Option<gix_ref::store::WriteReflog>,
17+
pub precompose_unicode: bool,
1518
}
1619

1720
/// Initialization
@@ -69,6 +72,13 @@ impl StageOne {
6972
)?;
7073
config.append(worktree_config);
7174
};
75+
let precompose_unicode = config
76+
.boolean("core", None, Core::PRECOMPOSE_UNICODE.name())
77+
.map(|v| Core::PRECOMPOSE_UNICODE.enrich_error(v))
78+
.transpose()
79+
.with_leniency(lenient)
80+
.map_err(Error::ConfigBoolean)?
81+
.unwrap_or_default();
7282

7383
let reflog = util::query_refupdates(&config, lenient)?;
7484
Ok(StageOne {
@@ -78,6 +88,7 @@ impl StageOne {
7888
lossy,
7989
object_hash,
8090
reflog,
91+
precompose_unicode,
8192
})
8293
}
8394
}

gix/src/config/cache/init.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ impl Cache {
2727
is_bare,
2828
object_hash,
2929
reflog: _,
30+
precompose_unicode: _,
3031
}: StageOne,
3132
git_dir: &std::path::Path,
3233
branch_name: Option<&gix_ref::FullNameRef>,

0 commit comments

Comments
 (0)