jdx/mise · error

failed to list Git-tracked files in {}: {}

Error message

failed to list Git-tracked files in {}: {}

What it means

Thrown when `git ls-files` (or a similar tracked-file listing command) fails for a dotfiles source directory after the repository root was found. Git's stderr, or the exit status if stderr is empty, is included with the source path. The library needs the tracked-file list to enumerate deployable files.

Source

Thrown at src/system/files.rs:1941

        .arg("-C")
        .arg(source)
        .arg("-c")
        .arg(safe)
        .arg("-c")
        .arg("core.autocrlf=false")
        .args(["ls-files", "-z", "--cached", "--stage", "--", "."])
        .stdout(std::process::Stdio::piped())
        .stderr(std::process::Stdio::piped());
    crate::git::sanitize_git_command(&mut command);
    let output = command.output().wrap_err_with(|| {
        format!(
            "failed to list Git-tracked files in {}",
            source.display_user()
        )
    })?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
        bail!(
            "failed to list Git-tracked files in {}: {}",
            source.display_user(),
            if stderr.is_empty() {
                output.status.to_string()
            } else {
                stderr
            }
        );
    }
    output
        .stdout
        .split(|byte| *byte == 0)
        .filter(|record| !record.is_empty())
        .map(|record| {
            let tab = record
                .iter()
                .position(|byte| *byte == b'\t')
                .ok_or_else(|| {

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Inspect the stderr embedded in the message and fix the underlying Git failure (e.g. remove a stale .git/index.lock).
  2. Run `git ls-files` manually in the source to reproduce and diagnose.
  3. Repair or re-clone the repository if its index is corrupted.
  4. Stop concurrent Git processes operating on the same repository.

Example fix

// before
$ mise files apply
error: failed to list Git-tracked files in ~/dotfiles: fatal: Unable to create '.../index.lock': File exists

// after
$ rm ~/dotfiles/.git/index.lock   # only when no git process is running
$ mise files apply
Defensive patterns

Strategy: retry

Validate before calling

use std::process::Command;
fn ensure_ls_files_ok(source: &std::path::Path) -> anyhow::Result<()> {
    let out = Command::new("git")
        .arg("ls-files")
        .current_dir(source)
        .output()?;
    if !out.status.success() {
        anyhow::bail!("git ls-files failed in {}: {}", source.display(),
            String::from_utf8_lossy(&out.stderr).trim());
    }
    Ok(())
}

Try / catch

match result {
    Err(e) if e.to_string().contains("failed to list Git-tracked files") => {
        // check for index.lock, wait, then retry once
        retry_after(|| run_apply(), std::time::Duration::from_secs(2), 2);
    }
    Err(e) => return Err(e),
    Ok(done) => done,
}

Prevention

When it happens

Trigger: Running a files/apply/unapply plan where `git ls-files` inside the source repository exits non-zero — e.g. corrupt index, detached/broken .git, out-of-memory, or locked index during a concurrent Git operation.

Common situations: A concurrent `git rebase`/`git merge` holds an index.lock; the Git index is corrupted; the repo works for rev-parse but the work tree state is broken; antivirus or backup tools lock files on Windows.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/cada209eee53d545. Report an issue: GitHub.