Skip to content

Commit 92c44ba

Browse files
committed
fix: proper submodule handling
Previously it was possible for `.git` files in directories to not trigger repository detection.
1 parent 39476e3 commit 92c44ba

File tree

4 files changed

+84
-6
lines changed

4 files changed

+84
-6
lines changed

gix-dir/src/walk/classify.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,6 @@ pub fn path(
164164
m.kind.into()
165165
}
166166
});
167-
if let Some(status) = maybe_status {
168-
return Ok(out.with_status(status).with_kind(kind, index_kind));
169-
}
170-
debug_assert!(maybe_status.is_none(), "It only communicates a single stae right now");
171167

172168
let mut maybe_upgrade_to_repository = |current_kind, find_harder: bool| {
173169
if recurse_repositories {
@@ -202,7 +198,14 @@ pub fn path(
202198
current_kind
203199
}
204200
};
201+
if let Some(status) = maybe_status {
202+
if kind == Some(entry::Kind::Directory) && index_kind == Some(entry::Kind::Repository) {
203+
kind = maybe_upgrade_to_repository(kind, false);
204+
}
205+
return Ok(out.with_status(status).with_kind(kind, index_kind));
206+
}
205207

208+
debug_assert!(maybe_status.is_none(), "It only communicates a single stae right now");
206209
if let Some(excluded) = ctx
207210
.excludes
208211
.as_mut()
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
walk_baseline.tar.xz
21
many.tar.xz
32
many-symlinks.tar.xz

gix-dir/tests/fixtures/many.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,16 @@ cp -R type-mismatch-icase-clash-dir-is-file type-mismatch-icase-clash-file-is-di
318318
)
319319
mkdir empty
320320
touch just-a-file
321+
322+
git init submodule
323+
(cd submodule
324+
touch empty && git add empty
325+
git commit -m upstream
326+
)
327+
328+
git clone submodule multiple-submodules
329+
(cd multiple-submodules
330+
git submodule add ../submodule submodule
331+
git submodule add ../submodule a/b
332+
git commit -m "add modules"
333+
)

gix-dir/tests/walk/mod.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2093,6 +2093,70 @@ fn root_can_be_pruned_early_with_pathspec() -> crate::Result {
20932093
Ok(())
20942094
}
20952095

2096+
#[test]
2097+
fn submodules() -> crate::Result {
2098+
let root = fixture("multiple-submodules");
2099+
let (out, entries) = collect(&root, |keep, ctx| walk(&root, &root, ctx, options_emit_all(), keep));
2100+
assert_eq!(
2101+
out,
2102+
walk::Outcome {
2103+
read_dir_calls: 2,
2104+
returned_entries: entries.len(),
2105+
seen_entries: 5,
2106+
}
2107+
);
2108+
let expected_content = [
2109+
entry_nokind(".git", DotGit),
2110+
entry(".gitmodules", Tracked, File).with_index_kind(File),
2111+
entry("a/b", Tracked, Repository).with_index_kind(Repository),
2112+
entry("empty", Tracked, File).with_index_kind(File),
2113+
entry("submodule", Tracked, Repository).with_index_kind(Repository),
2114+
];
2115+
assert_eq!(entries, expected_content, "submodules are detected as repositories");
2116+
2117+
let (out1, entries) = try_collect_filtered_opts_collect(
2118+
&root,
2119+
|keep, ctx| walk(&root, &root, ctx, options_emit_all(), keep),
2120+
None::<&str>,
2121+
Options {
2122+
fresh_index: false,
2123+
..Default::default()
2124+
},
2125+
)?;
2126+
assert_eq!(out1, out, "the output matches precisely");
2127+
assert_eq!(
2128+
entries, expected_content,
2129+
"this is also the case if the index isn't considered fresh"
2130+
);
2131+
2132+
let (out2, entries) = try_collect_filtered_opts_collect(
2133+
&root,
2134+
|keep, ctx| {
2135+
walk(
2136+
&root,
2137+
&root,
2138+
ctx,
2139+
walk::Options {
2140+
ignore_case: true,
2141+
..options_emit_all()
2142+
},
2143+
keep,
2144+
)
2145+
},
2146+
None::<&str>,
2147+
Options {
2148+
fresh_index: false,
2149+
..Default::default()
2150+
},
2151+
)?;
2152+
assert_eq!(out2, out, "the output matches precisely, even with ignore-case");
2153+
assert_eq!(
2154+
entries, expected_content,
2155+
"ignore case doesn't change anything (even though our search is quite different)"
2156+
);
2157+
Ok(())
2158+
}
2159+
20962160
#[test]
20972161
fn cancel_with_collection_does_not_fail() -> crate::Result {
20982162
struct CancelDelegate {
@@ -2105,7 +2169,6 @@ fn cancel_with_collection_does_not_fail() -> crate::Result {
21052169
walk::Action::Cancel
21062170
} else {
21072171
self.emits_left_until_cancel -= 1;
2108-
dbg!(self.emits_left_until_cancel);
21092172
walk::Action::Continue
21102173
}
21112174
}

0 commit comments

Comments
 (0)