Skip to content

Commit 1ebd6c7

Browse files
committed
add tests that show what happens with allow-lists and / in root (#1458)
1 parent 4f67be4 commit 1ebd6c7

File tree

2 files changed

+236
-0
lines changed

2 files changed

+236
-0
lines changed

gix-dir/tests/fixtures/many.sh

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,83 @@ git clone submodule multiple-submodules
351351
git submodule add ../submodule a/b
352352
git commit -m "add modules"
353353
)
354+
355+
git clone submodule one-ignored-submodule
356+
(cd one-ignored-submodule
357+
git submodule add ../submodule submodule
358+
echo '/submodule/' > .gitignore
359+
echo '*' > submodule/.gitignore
360+
git commit -m "add seemingly ignored submodule"
361+
)
362+
363+
git init slash-in-root-and-negated
364+
(cd slash-in-root-and-negated
365+
cat <<'EOF' >.gitignore
366+
/
367+
!file
368+
!*.md
369+
!.github
370+
!.github/**
371+
EOF
372+
touch file readme.md
373+
mkdir .github
374+
touch .github/workflow.yml
375+
git add .github readme.md .gitignore
376+
git commit -m "init"
377+
)
378+
379+
git init star-in-root-and-negated
380+
(cd star-in-root-and-negated
381+
cat <<'EOF' >.gitignore
382+
*
383+
!file
384+
!.gitignore
385+
!*.md
386+
!.github
387+
!.github/**
388+
EOF
389+
touch file readme.md
390+
mkdir .github
391+
touch .github/workflow.yml
392+
git add .github readme.md .gitignore
393+
git commit -m "init"
394+
)
395+
396+
git init slash-in-subdir-and-negated
397+
(cd slash-in-subdir-and-negated
398+
mkdir sub
399+
(cd sub
400+
cat <<'EOF' >.gitignore
401+
/
402+
!file
403+
!*.md
404+
!.github
405+
!.github/**
406+
EOF
407+
touch file readme.md
408+
mkdir .github
409+
touch .github/workflow.yml
410+
git add .github readme.md .gitignore
411+
git commit -m "init"
412+
)
413+
)
414+
415+
git init star-in-subdir-and-negated
416+
(cd star-in-subdir-and-negated
417+
mkdir sub
418+
(cd sub
419+
cat <<'EOF' >.gitignore
420+
*
421+
!file
422+
!.gitignore
423+
!*.md
424+
!.github
425+
!.github/**
426+
EOF
427+
touch file readme.md
428+
mkdir .github
429+
touch .github/workflow.yml
430+
git add .github readme.md .gitignore
431+
git commit -m "init"
432+
)
433+
)

gix-dir/tests/walk/mod.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4276,3 +4276,159 @@ fn type_mismatch_ignore_case_clash_file_is_dir() {
42764276
If there was no special handling for this, it would have found the file (`d` in the index, icase), which would have been wrong."
42774277
);
42784278
}
4279+
4280+
#[test]
4281+
fn top_level_slash_with_negations() -> crate::Result {
4282+
for repo_name in ["slash-in-root-and-negated", "star-in-root-and-negated"] {
4283+
let root = fixture(repo_name);
4284+
let ((out, _root), entries) = collect(&root, None, |keep, ctx| walk(&root, ctx, options_emit_all(), keep));
4285+
assert_eq!(
4286+
out,
4287+
walk::Outcome {
4288+
read_dir_calls: 0,
4289+
returned_entries: entries.len(),
4290+
seen_entries: 1,
4291+
}
4292+
);
4293+
assert_eq!(
4294+
entries,
4295+
&[entry("", Ignored(Expendable), Directory)],
4296+
"This is wrong - the root can never be listed"
4297+
);
4298+
4299+
let ((out, _root), entries) = collect(&root, None, |keep, ctx| {
4300+
walk(
4301+
&root,
4302+
ctx,
4303+
walk::Options {
4304+
for_deletion: Some(ForDeletionMode::FindRepositoriesInIgnoredDirectories),
4305+
emit_tracked: false,
4306+
..options_emit_all()
4307+
},
4308+
keep,
4309+
)
4310+
});
4311+
assert_eq!(
4312+
out,
4313+
walk::Outcome {
4314+
read_dir_calls: 2,
4315+
returned_entries: entries.len(),
4316+
seen_entries: 5,
4317+
}
4318+
);
4319+
assert_eq!(
4320+
entries,
4321+
&[
4322+
entry_nokind(".git", Ignored(Expendable))
4323+
.with_property(DotGit)
4324+
.with_match(Always),
4325+
entry("file", Ignored(Expendable), File)
4326+
],
4327+
"This is still wrong, but consistent within what it should do.\
4328+
Top-level `.git` should always be Pruned, even if ignored.\
4329+
Except for `file` which should be untracked."
4330+
);
4331+
}
4332+
Ok(())
4333+
}
4334+
4335+
#[test]
4336+
fn subdir_slash_with_negations() -> crate::Result {
4337+
for repo_name in ["slash-in-subdir-and-negated", "star-in-subdir-and-negated"] {
4338+
let root = fixture(repo_name);
4339+
let ((out, _root), entries) = collect(&root, None, |keep, ctx| walk(&root, ctx, options_emit_all(), keep));
4340+
assert_eq!(
4341+
out,
4342+
walk::Outcome {
4343+
read_dir_calls: 3,
4344+
returned_entries: entries.len(),
4345+
seen_entries: 5,
4346+
}
4347+
);
4348+
assert_eq!(
4349+
entries,
4350+
&[
4351+
entry_nokind(".git", Pruned).with_property(DotGit).with_match(Always),
4352+
entry("sub/.github/workflow.yml", Tracked, File),
4353+
entry("sub/.gitignore", Tracked, File),
4354+
entry("sub/file", Untracked, File),
4355+
entry("sub/readme.md", Tracked, File),
4356+
],
4357+
"subdirectory matches work as expected, also with a `/` which has no bearing."
4358+
);
4359+
4360+
let ((out, _root), entries) = collect(&root, None, |keep, ctx| {
4361+
walk(
4362+
&root,
4363+
ctx,
4364+
walk::Options {
4365+
for_deletion: Some(ForDeletionMode::FindRepositoriesInIgnoredDirectories),
4366+
emit_tracked: false,
4367+
..options_emit_all()
4368+
},
4369+
keep,
4370+
)
4371+
});
4372+
assert_eq!(
4373+
out,
4374+
walk::Outcome {
4375+
read_dir_calls: 3,
4376+
returned_entries: entries.len(),
4377+
seen_entries: 5,
4378+
}
4379+
);
4380+
assert_eq!(
4381+
entries,
4382+
&[
4383+
entry_nokind(".git", Pruned).with_property(DotGit).with_match(Always),
4384+
entry("sub/file", Untracked, File)
4385+
],
4386+
"This is expected, and the `.git` top-level is pruned."
4387+
);
4388+
}
4389+
Ok(())
4390+
}
4391+
4392+
#[test]
4393+
fn one_ignored_submodule() -> crate::Result {
4394+
let root = fixture("one-ignored-submodule");
4395+
let ((out, _root), entries) = collect(&root, None, |keep, ctx| walk(&root, ctx, options_emit_all(), keep));
4396+
assert_eq!(
4397+
out,
4398+
walk::Outcome {
4399+
read_dir_calls: 1,
4400+
returned_entries: entries.len(),
4401+
seen_entries: 5,
4402+
}
4403+
);
4404+
assert_eq!(
4405+
entries,
4406+
&[
4407+
entry_nokind(".git", Pruned).with_property(DotGit).with_match(Always),
4408+
entry(".gitignore", Untracked, File),
4409+
entry(".gitmodules", Tracked, File),
4410+
entry("empty", Tracked, File),
4411+
entry("submodule", Tracked, Repository),
4412+
],
4413+
"when traversing the worktree root, this is correct, the submodule doesn't count as ignored"
4414+
);
4415+
4416+
let troot = root.join("submodule");
4417+
let ((out, _root), entries) = collect(&root, Some(&troot), |keep, ctx| {
4418+
walk(&root, ctx, options_emit_all(), keep)
4419+
});
4420+
assert_eq!(
4421+
out,
4422+
walk::Outcome {
4423+
read_dir_calls: 0,
4424+
returned_entries: entries.len(),
4425+
seen_entries: 1
4426+
}
4427+
);
4428+
assert_eq!(
4429+
entries,
4430+
&[entryps("submodule", Tracked, Repository, Verbatim)],
4431+
"The submodule is simply tracked, it doesn't count as ignored"
4432+
);
4433+
Ok(())
4434+
}

0 commit comments

Comments
 (0)