rust-lang/cargo · error · anyhow::Error

more than one of .hg, .git, .pijul, .fossil configurations f

Error message

more than one of .hg, .git, .pijul, .fossil configurations found and the ignore file can't be filled in as a result. specify --vcs to override detection

What it means

During `cargo init`, if --vcs was not passed Cargo auto-detects the existing VCS by checking for .git/.hg/.pijul/.fossil. When MORE than one of those directories is present, it cannot decide which ignore-file format (.gitignore vs .hgignore vs .gitignore-fossil vs .ignore) to write, so it bails at cargo_new.rs:580-586 asking the user to disambiguate with --vcs.

Source

Thrown at src/ops/cargo_new.rs:581

        if path.join(".hg").exists() {
            version_control = Some(VersionControl::Hg);
            num_detected_vcses += 1;
        }

        if path.join(".pijul").exists() {
            version_control = Some(VersionControl::Pijul);
            num_detected_vcses += 1;
        }

        if path.join(".fossil").exists() {
            version_control = Some(VersionControl::Fossil);
            num_detected_vcses += 1;
        }

        // if none exists, maybe create git, like in `cargo new`

        if num_detected_vcses > 1 {
            anyhow::bail!(
                "more than one of .hg, .git, .pijul, .fossil configurations \
                 found and the ignore file can't be filled in as \
                 a result. specify --vcs to override detection"
            );
        }
    }

    let mkopts = MkOptions {
        version_control,
        path,
        name,
        source_files: src_paths_types,
        edition: opts.edition.as_deref(),
        registry: opts.registry.as_deref(),
    };

    mk(gctx, &mkopts).with_context(|| {
        format!(

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Pass --vcs explicitly to override detection: `cargo init --vcs git`
  2. Remove the stale VCS directory you no longer use (e.g. `rm -rf .hg`) then re-run
  3. Pass `--vcs none` to skip ignore-file generation entirely

Example fix

# before (.git and .hg both present)
cargo init
# after (option A)
cargo init --vcs git
# after (option B)
rm -rf .hg && cargo init
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn count_vcs_dirs(dir: &Path) -> usize {
    [".git", ".hg", ".pijul", ".fossil"].iter().filter(|d| dir.join(d).exists()).count()
}

if count_vcs_dirs(dir) > 1 && vcs_arg.is_none() { /* force user to pass --vcs */ }

Type guard

import { existsSync } from 'fs';
import { join } from 'path';
function detectSingleVcs(dir: string): string | null {
  const found = ['.git','.hg','.pijul','.fossil'].filter(d => existsSync(join(dir, d)));
  return found.length === 1 ? found[0] : null;
}

Prevention

When it happens

Trigger: `cargo init` in a directory that contains both a `.git/` and a `.hg/` (or .pijul/, .fossil/) - e.g. a repo migrated from Mercurial to Git where the old .hg was left in place, or a directory bind-mounted from another VCS workspace.

Common situations: Half-finished VCS migrations (git repo that still contains .hg); CI checkouts that leave auxiliary VCS metadata; users experimenting with Pijul/Fossil alongside Git; tooling that creates a .git skeleton regardless of the real VCS.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/4ef530fca75b75f6.json. Report an issue: GitHub.