Skip to content

Commit a80a150

Browse files
authored
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.
2 parents 4b535bf + b3b3203 commit a80a150

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

gix-discover/src/upwards/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub(crate) mod function {
168168
}
169169
}
170170
}
171-
if cursor.parent().is_some_and(|p| p.as_os_str().is_empty()) {
171+
if cursor.as_os_str().is_empty() || cursor.as_os_str() == OsStr::new(".") {
172172
cursor = cwd.to_path_buf();
173173
dir_made_absolute = true;
174174
}

gix-discover/tests/isolated.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@ use std::path::{Path, PathBuf};
33
use gix_discover::upwards::Options;
44
use serial_test::serial;
55

6+
#[test]
7+
#[serial]
8+
fn in_cwd_upwards_from_nested_dir() -> gix_testtools::Result {
9+
let repo = gix_testtools::scripted_fixture_read_only("make_basic_repo.sh")?;
10+
11+
let _keep = gix_testtools::set_current_dir(repo)?;
12+
for dir in ["subdir", "some/very/deeply/nested/subdir"] {
13+
let (repo_path, _trust) = gix_discover::upwards(Path::new(dir))?;
14+
assert_eq!(
15+
repo_path.kind(),
16+
gix_discover::repository::Kind::WorkTree { linked_git_dir: None },
17+
);
18+
assert_eq!(repo_path.as_ref(), Path::new("."), "{dir}");
19+
}
20+
Ok(())
21+
}
22+
623
#[test]
724
#[serial]
825
fn upwards_bare_repo_with_index() -> gix_testtools::Result {
@@ -48,18 +65,21 @@ fn in_cwd_upwards_nonbare_repo_without_index() -> gix_testtools::Result {
4865
fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Result {
4966
let repo = gix_testtools::scripted_fixture_read_only("make_basic_repo.sh")?;
5067

51-
let _keep = gix_testtools::set_current_dir(repo.join("subdir"))?;
68+
let _keep = gix_testtools::set_current_dir(repo.join("some"))?;
5269
let cwd = std::env::current_dir()?;
5370

5471
for (search_dir, ceiling_dir_component) in [
5572
(".", ".."),
5673
(".", "./.."),
5774
("./.", "./.."),
5875
(".", "./does-not-exist/../.."),
76+
("./././very/deeply/nested/subdir", ".."),
77+
("very/deeply/nested/subdir", ".."),
5978
] {
79+
let search_dir = Path::new(search_dir);
6080
let ceiling_dir = cwd.join(ceiling_dir_component);
6181
let (repo_path, _trust) = gix_discover::upwards_opts(
62-
search_dir.as_ref(),
82+
search_dir,
6383
Options {
6484
ceiling_dirs: vec![ceiling_dir],
6585
..Default::default()
@@ -68,12 +88,12 @@ fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Re
6888
.expect("ceiling dir should allow us to discover the repo");
6989
assert_repo_is_current_workdir(repo_path, Path::new(".."));
7090

71-
let (repo_path, _trust) = gix_discover::upwards_opts(search_dir.as_ref(), Default::default())
72-
.expect("without ceiling dir we see the same");
91+
let (repo_path, _trust) =
92+
gix_discover::upwards_opts(search_dir, Default::default()).expect("without ceiling dir we see the same");
7393
assert_repo_is_current_workdir(repo_path, Path::new(".."));
7494

7595
let (repo_path, _trust) = gix_discover::upwards_opts(
76-
search_dir.as_ref(),
96+
search_dir,
7797
Options {
7898
ceiling_dirs: vec![PathBuf::from("..")],
7999
..Default::default()
@@ -83,15 +103,22 @@ fn upwards_with_relative_directories_and_optional_ceiling() -> gix_testtools::Re
83103
assert_repo_is_current_workdir(repo_path, Path::new(".."));
84104

85105
let err = gix_discover::upwards_opts(
86-
search_dir.as_ref(),
106+
search_dir,
87107
Options {
88108
ceiling_dirs: vec![PathBuf::from(".")],
89109
..Default::default()
90110
},
91111
)
92112
.unwrap_err();
93113

94-
assert!(matches!(err, gix_discover::upwards::Error::NoMatchingCeilingDir));
114+
if search_dir.parent() == Some(".".as_ref()) || search_dir.parent() == Some("".as_ref()) {
115+
assert!(matches!(err, gix_discover::upwards::Error::NoMatchingCeilingDir));
116+
} else {
117+
assert!(matches!(
118+
err,
119+
gix_discover::upwards::Error::NoGitRepositoryWithinCeiling { .. }
120+
));
121+
}
95122
}
96123

97124
Ok(())

0 commit comments

Comments
 (0)