Skip to content

Decide: should .gitignore require an actual .git repository to take effect? #346

Description

@akiomik

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: .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

  1. 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.
  2. 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.

  3. 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.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions