You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While investigating #140/#141, one of the two root causes behind #141 (build/packaging environments picking up unwanted markdown files under target/) turned out to be this: .gitignore handling only takes effect when an actual .git directory is present.
respect-gitignore (src/config/lint.rs) is passed straight through to ignore::WalkBuilder::git_ignore(). That crate has a separate, independent setting, require_git, which defaults to true and is never touched by mado. The practical effect: with respect-gitignore = true (the default) but no .git directory (e.g. a source tarball extracted for distro packaging, a Docker image built from an export without .git), .gitignore is silently not respected at all, and anything it lists (target/, build output, etc.) gets walked and linted.
This issue is not about deciding a fix. The goal here is to reach a decision on what the intended behavior should be; a follow-up PR can implement whatever we land on.
How other tools in the same space behave
All of the following was verified empirically (not just from docs), using a .gitignore-excluded directory with and without an actual .git present.
Tool
Respects .gitignore without .git?
Can the behavior be switched?
ripgrep (rg) — same author as the ignore crate mado uses
No (default)
Yes — --no-require-git opts into honoring .gitignore without .git; --require-git restores the default explicitly
ruff
No
No flag found; --respect-gitignore does not change this
biome
Yes (unconditional)
No — no way to require a real repo
oxlint
Yes (unconditional)
No — and note: its docs claim --no-ignore disables .gitignore handling too, but that did not hold up when tested
mado (current)
No
No — respect-gitignore toggles whether .gitignore is consulted at all, but not whether a real repo is required first
Notes from testing:
rg and ruff both build on the same default (require_git: true) — rg is actually the crate author's own tool, so this default is a deliberate, considered choice, not an oversight.
biome's vcs.useIgnoreFile also claims to cover .ignore files (rg/mado's separate ignore-file convention), and does when .ignore is the only ignore file present — but when both .ignore and .gitignore exist together, only .gitignore took effect in testing. Undocumented, possibly a biome quirk, noted here for completeness but not central to this decision.
mado's own docs (pkg/json-schema/mado.json) describe respect-gitignore as "Exclude files that are ignored by .gitignore" with no mention of the .git-presence precondition — so regardless of which way this issue is resolved, the current behavior is under-documented.
The actual decision to make
Should respect-gitignore = true require an actual .git directory, or honor .gitignore unconditionally?
Arguments raised on both sides during the investigation:
For keeping the git requirement (current behavior, matches rg/ruff):.gitignore is inherently a git artifact; two other well-regarded Rust tools in this space (one of them being the ignore crate's own author) made the same default choice, so users coming from that ecosystem may find git-gated behavior the less surprising option, not more. A "source tarball / Docker image with only .gitignore and no .git" scenario is arguably a smell on the producer's side (e.g. a missing/incomplete .dockerignore) rather than a case mado needs to accommodate.
For dropping the git requirement (matches biome/oxlint):respect-gitignore is an explicit, dedicated, separately-documented option distinct from respect-ignore — someone who sets it to true may reasonably expect it to do what its name and description say, without a silent precondition that isn't mentioned anywhere in the docs. This is close to what actually happened in 0.2.2: Command checks fail due to color output and trying to check non-test files #141: neither the reporter nor the maintainer anticipated the git requirement.
Neither argument is clearly decisive on its own; rg and ruff's precedent is real evidence that "requires git" is not an unreasonable default, which tempers how strong the second argument is.
Independent of (1): should there be an explicit knob to control this, the way rg exposes --require-git / --no-require-git on top of its default? This is orthogonal to what the default should be — rg proves you can keep a conservative default and still offer an escape hatch.
At minimum, whatever we decide on (1) and (2), the current git-presence precondition should probably be documented (pkg/json-schema/mado.json, and possibly README) since right now it's an undocumented implementation detail inherited silently from the ignore crate's default.
Context
While investigating #140/#141, one of the two root causes behind #141 (build/packaging environments picking up unwanted markdown files under
target/) turned out to be this:.gitignorehandling only takes effect when an actual.gitdirectory is present.respect-gitignore(src/config/lint.rs) is passed straight through toignore::WalkBuilder::git_ignore(). That crate has a separate, independent setting,require_git, which defaults totrueand is never touched by mado. The practical effect: withrespect-gitignore = true(the default) but no.gitdirectory (e.g. a source tarball extracted for distro packaging, a Docker image built from an export without.git),.gitignoreis silently not respected at all, and anything it lists (target/, build output, etc.) gets walked and linted.This issue is not about deciding a fix. The goal here is to reach a decision on what the intended behavior should be; a follow-up PR can implement whatever we land on.
How other tools in the same space behave
All of the following was verified empirically (not just from docs), using a
.gitignore-excluded directory with and without an actual.gitpresent..gitignorewithout.git?ignorecrate mado uses--no-require-gitopts into honoring.gitignorewithout.git;--require-gitrestores the default explicitly--respect-gitignoredoes not change this--no-ignoredisables.gitignorehandling too, but that did not hold up when testedrespect-gitignoretoggles whether.gitignoreis consulted at all, but not whether a real repo is required firstNotes from testing:
require_git: true) — rg is actually the crate author's own tool, so this default is a deliberate, considered choice, not an oversight.vcs.useIgnoreFilealso claims to cover.ignorefiles (rg/mado's separate ignore-file convention), and does when.ignoreis the only ignore file present — but when both.ignoreand.gitignoreexist together, only.gitignoretook effect in testing. Undocumented, possibly a biome quirk, noted here for completeness but not central to this decision.pkg/json-schema/mado.json) describerespect-gitignoreas "Exclude files that are ignored by.gitignore" with no mention of the.git-presence precondition — so regardless of which way this issue is resolved, the current behavior is under-documented.The actual decision to make
Should
respect-gitignore = truerequire an actual.gitdirectory, or honor.gitignoreunconditionally?Arguments raised on both sides during the investigation:
.gitignoreis inherently a git artifact; two other well-regarded Rust tools in this space (one of them being theignorecrate's own author) made the same default choice, so users coming from that ecosystem may find git-gated behavior the less surprising option, not more. A "source tarball / Docker image with only.gitignoreand no.git" scenario is arguably a smell on the producer's side (e.g. a missing/incomplete.dockerignore) rather than a case mado needs to accommodate.respect-gitignoreis an explicit, dedicated, separately-documented option distinct fromrespect-ignore— someone who sets it totruemay reasonably expect it to do what its name and description say, without a silent precondition that isn't mentioned anywhere in the docs. This is close to what actually happened in 0.2.2: Command checks fail due to color output and trying to check non-test files #141: neither the reporter nor the maintainer anticipated the git requirement.Independent of (1): should there be an explicit knob to control this, the way rg exposes
--require-git/--no-require-giton top of its default? This is orthogonal to what the default should be — rg proves you can keep a conservative default and still offer an escape hatch.At minimum, whatever we decide on (1) and (2), the current git-presence precondition should probably be documented (
pkg/json-schema/mado.json, and possibly README) since right now it's an undocumented implementation detail inherited silently from theignorecrate's default.Related
output::concise::tests::display_fmt,output::markdownlint::tests::display_fmt,output::mdl::tests::display_fmtfail #140