Skip to content

Commit

Permalink
add tests that show what happens with allow-lists and / in root (#1458
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Byron committed Jul 23, 2024
1 parent 4f67be4 commit 1ebd6c7
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 0 deletions.
80 changes: 80 additions & 0 deletions gix-dir/tests/fixtures/many.sh
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,83 @@ git clone submodule multiple-submodules
git submodule add ../submodule a/b
git commit -m "add modules"
)

git clone submodule one-ignored-submodule
(cd one-ignored-submodule
git submodule add ../submodule submodule
echo '/submodule/' > .gitignore
echo '*' > submodule/.gitignore
git commit -m "add seemingly ignored submodule"
)

git init slash-in-root-and-negated
(cd slash-in-root-and-negated
cat <<'EOF' >.gitignore
/
!file
!*.md
!.github
!.github/**
EOF
touch file readme.md
mkdir .github
touch .github/workflow.yml
git add .github readme.md .gitignore
git commit -m "init"
)

git init star-in-root-and-negated
(cd star-in-root-and-negated
cat <<'EOF' >.gitignore
*
!file
!.gitignore
!*.md
!.github
!.github/**
EOF
touch file readme.md
mkdir .github
touch .github/workflow.yml
git add .github readme.md .gitignore
git commit -m "init"
)

git init slash-in-subdir-and-negated
(cd slash-in-subdir-and-negated
mkdir sub
(cd sub
cat <<'EOF' >.gitignore
/
!file
!*.md
!.github
!.github/**
EOF
touch file readme.md
mkdir .github
touch .github/workflow.yml
git add .github readme.md .gitignore
git commit -m "init"
)
)

git init star-in-subdir-and-negated
(cd star-in-subdir-and-negated
mkdir sub
(cd sub
cat <<'EOF' >.gitignore
*
!file
!.gitignore
!*.md
!.github
!.github/**
EOF
touch file readme.md
mkdir .github
touch .github/workflow.yml
git add .github readme.md .gitignore
git commit -m "init"
)
)
156 changes: 156 additions & 0 deletions gix-dir/tests/walk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4276,3 +4276,159 @@ fn type_mismatch_ignore_case_clash_file_is_dir() {
If there was no special handling for this, it would have found the file (`d` in the index, icase), which would have been wrong."
);
}

#[test]
fn top_level_slash_with_negations() -> crate::Result {
for repo_name in ["slash-in-root-and-negated", "star-in-root-and-negated"] {
let root = fixture(repo_name);
let ((out, _root), entries) = collect(&root, None, |keep, ctx| walk(&root, ctx, options_emit_all(), keep));
assert_eq!(
out,
walk::Outcome {
read_dir_calls: 0,
returned_entries: entries.len(),
seen_entries: 1,
}
);
assert_eq!(
entries,
&[entry("", Ignored(Expendable), Directory)],
"This is wrong - the root can never be listed"
);

let ((out, _root), entries) = collect(&root, None, |keep, ctx| {
walk(
&root,
ctx,
walk::Options {
for_deletion: Some(ForDeletionMode::FindRepositoriesInIgnoredDirectories),
emit_tracked: false,
..options_emit_all()
},
keep,
)
});
assert_eq!(
out,
walk::Outcome {
read_dir_calls: 2,
returned_entries: entries.len(),
seen_entries: 5,
}
);
assert_eq!(
entries,
&[
entry_nokind(".git", Ignored(Expendable))
.with_property(DotGit)
.with_match(Always),
entry("file", Ignored(Expendable), File)
],
"This is still wrong, but consistent within what it should do.\
Top-level `.git` should always be Pruned, even if ignored.\
Except for `file` which should be untracked."
);
}
Ok(())
}

#[test]
fn subdir_slash_with_negations() -> crate::Result {
for repo_name in ["slash-in-subdir-and-negated", "star-in-subdir-and-negated"] {
let root = fixture(repo_name);
let ((out, _root), entries) = collect(&root, None, |keep, ctx| walk(&root, ctx, options_emit_all(), keep));
assert_eq!(
out,
walk::Outcome {
read_dir_calls: 3,
returned_entries: entries.len(),
seen_entries: 5,
}
);
assert_eq!(
entries,
&[
entry_nokind(".git", Pruned).with_property(DotGit).with_match(Always),
entry("sub/.github/workflow.yml", Tracked, File),
entry("sub/.gitignore", Tracked, File),
entry("sub/file", Untracked, File),
entry("sub/readme.md", Tracked, File),
],
"subdirectory matches work as expected, also with a `/` which has no bearing."
);

let ((out, _root), entries) = collect(&root, None, |keep, ctx| {
walk(
&root,
ctx,
walk::Options {
for_deletion: Some(ForDeletionMode::FindRepositoriesInIgnoredDirectories),
emit_tracked: false,
..options_emit_all()
},
keep,
)
});
assert_eq!(
out,
walk::Outcome {
read_dir_calls: 3,
returned_entries: entries.len(),
seen_entries: 5,
}
);
assert_eq!(
entries,
&[
entry_nokind(".git", Pruned).with_property(DotGit).with_match(Always),
entry("sub/file", Untracked, File)
],
"This is expected, and the `.git` top-level is pruned."
);
}
Ok(())
}

#[test]
fn one_ignored_submodule() -> crate::Result {
let root = fixture("one-ignored-submodule");
let ((out, _root), entries) = collect(&root, None, |keep, ctx| walk(&root, ctx, options_emit_all(), keep));
assert_eq!(
out,
walk::Outcome {
read_dir_calls: 1,
returned_entries: entries.len(),
seen_entries: 5,
}
);
assert_eq!(
entries,
&[
entry_nokind(".git", Pruned).with_property(DotGit).with_match(Always),
entry(".gitignore", Untracked, File),
entry(".gitmodules", Tracked, File),
entry("empty", Tracked, File),
entry("submodule", Tracked, Repository),
],
"when traversing the worktree root, this is correct, the submodule doesn't count as ignored"
);

let troot = root.join("submodule");
let ((out, _root), entries) = collect(&root, Some(&troot), |keep, ctx| {
walk(&root, ctx, options_emit_all(), keep)
});
assert_eq!(
out,
walk::Outcome {
read_dir_calls: 0,
returned_entries: entries.len(),
seen_entries: 1
}
);
assert_eq!(
entries,
&[entryps("submodule", Tracked, Repository, Verbatim)],
"The submodule is simply tracked, it doesn't count as ignored"
);
Ok(())
}

0 comments on commit 1ebd6c7

Please sign in to comment.