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
- Inspect the stderr embedded in the message and fix the underlying Git failure (e.g. remove a stale .git/index.lock).
- Run `git ls-files` manually in the source to reproduce and diagnose.
- Repair or re-clone the repository if its index is corrupted.
- 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
- Avoid running mise files operations while a git merge/rebase is in progress in the source repo.
- Clear stale .git/index.lock only after confirming no git process is running.
- Run `git fsck` periodically on the dotfiles repo.
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
- failed to locate Git repository for {}: {}
- failed rename: {} -> {}: {err}
- {err} dotfiles: rollback failed: {rollback_err}
- {}
- comparing checkpoints requires git
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/cada209eee53d545.
Report an issue: GitHub.