Skip to content

Commit 7c1e027

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

File tree

2 files changed

+184
-0
lines changed

2 files changed

+184
-0
lines changed

gix-dir/tests/fixtures/many.sh

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

gix-dir/tests/walk/mod.rs

+112
Original file line numberDiff line numberDiff line change
@@ -4276,3 +4276,115 @@ 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+
}

0 commit comments

Comments
 (0)