1
1
mirror of https://github.com/Byron/gitoxide synced 2025-10-06 01:52:40 +02:00

fix: discover upwards to cwd

The upwards search for the repository directory takes a directory as
input and then walks through the parents. It turns out that it was
broken when the repository was the same as the working directory.

The code checked when the directory components had been stripped to "", in
case the directory was replaced with `cwd.parent()`, so the loop missed
to check `cwd` itself. If the input directory was "./something", then
"." was checked which then succeeded.
This commit is contained in:
Sebastian Thiel
2025-09-22 07:40:36 +02:00
committed by GitHub
2 changed files with 35 additions and 8 deletions

View File

@@ -168,7 +168,7 @@ pub(crate) mod function {
}
}
}
if cursor.parent().is_some_and(|p| p.as_os_str().is_empty()) {
if cursor.as_os_str().is_empty() || cursor.as_os_str() == OsStr::new(".") {
cursor = cwd.to_path_buf();
dir_made_absolute = true;
}

View File

@@ -3,6 +3,23 @@ use std::path::{Path, PathBuf};
use gix_discover::upwards::Options;
use serial_test::serial;
#[test]
#[serial]
fn in_cwd_upwards_from_nested_dir() -> gix_testtools::Result {
let repo = gix_testtools::scripted_fixture_read_only("make_basic_repo.sh")?;
let _keep = gix_testtools::set_current_dir(repo)?;
for dir in ["subdir", "some/very/deeply/nested/subdir"] {
let (repo_path, _trust) = gix_discover::upwards(Path::new(dir))?;
assert_eq!(
repo_path.kind(),
gix_discover::repository::Kind::WorkTree { linked_git_dir: None },
);
assert_eq!(repo_path.as_ref(), Path::new("."), "{dir}");
}
Ok(())
}
#[test]
#[serial]
fn upwards_bare_repo_with_index() -> gix_testtools::Result {
@@ -48,7 +65,7 @@ fn in_cwd_upwards_nonbare_repo_without_index() -> gix_testtools::Result {
fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Result {
let repo = gix_testtools::scripted_fixture_read_only("make_basic_repo.sh")?;
let _keep = gix_testtools::set_current_dir(repo.join("subdir"))?;
let _keep = gix_testtools::set_current_dir(repo.join("some"))?;
let cwd = std::env::current_dir()?;
for (search_dir, ceiling_dir_component) in [
@@ -56,10 +73,13 @@ fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Re
(".", "./.."),
("./.", "./.."),
(".", "./does-not-exist/../.."),
("./././very/deeply/nested/subdir", ".."),
("very/deeply/nested/subdir", ".."),
] {
let search_dir = Path::new(search_dir);
let ceiling_dir = cwd.join(ceiling_dir_component);
let (repo_path, _trust) = gix_discover::upwards_opts(
search_dir.as_ref(),
search_dir,
Options {
ceiling_dirs: vec![ceiling_dir],
..Default::default()
@@ -68,12 +88,12 @@ fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Re
.expect("ceiling dir should allow us to discover the repo");
assert_repo_is_current_workdir(repo_path, Path::new(".."));
let (repo_path, _trust) = gix_discover::upwards_opts(search_dir.as_ref(), Default::default())
.expect("without ceiling dir we see the same");
let (repo_path, _trust) =
gix_discover::upwards_opts(search_dir, Default::default()).expect("without ceiling dir we see the same");
assert_repo_is_current_workdir(repo_path, Path::new(".."));
let (repo_path, _trust) = gix_discover::upwards_opts(
search_dir.as_ref(),
search_dir,
Options {
ceiling_dirs: vec![PathBuf::from("..")],
..Default::default()
@@ -83,7 +103,7 @@ fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Re
assert_repo_is_current_workdir(repo_path, Path::new(".."));
let err = gix_discover::upwards_opts(
search_dir.as_ref(),
search_dir,
Options {
ceiling_dirs: vec![PathBuf::from(".")],
..Default::default()
@@ -91,7 +111,14 @@ fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Re
)
.unwrap_err();
assert!(matches!(err, gix_discover::upwards::Error::NoMatchingCeilingDir));
if search_dir.parent() == Some(".".as_ref()) || search_dir.parent() == Some("".as_ref()) {
assert!(matches!(err, gix_discover::upwards::Error::NoMatchingCeilingDir));
} else {
assert!(matches!(
err,
gix_discover::upwards::Error::NoGitRepositoryWithinCeiling { .. }
));
}
}
Ok(())