{"record":{"id":"ee466ab64263dffc","repo":"jdx/mise","slug":"cannot-check-staged-changes-git-is-unavailable","errorCode":null,"errorMessage":"cannot check staged changes: git is unavailable","messagePattern":"cannot check staged changes: git is unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/apply.rs","lineNumber":847,"sourceCode":"    repo.restored_object_at(&head, &entry.tree_path(path)?)\n}\n\n/// Read each containing checkout's index once per preflight, not once per\n/// incoming file. Never retain this observation across subsequent validation.\npub(super) fn staged_paths<'a>(paths: impl Iterator<Item = &'a Path>) -> Result<BTreeSet<PathBuf>> {\n    let roots: BTreeSet<_> = paths\n        .filter_map(|path| {\n            path.ancestors()\n                .find(|dir| dir.join(\".git\").exists())\n                .map(Path::to_path_buf)\n        })\n        .collect();\n    let mut staged = BTreeSet::new();\n    if roots.is_empty() {\n        return Ok(staged);\n    }\n    let Some(git) = crate::git::plumbing_binary() else {\n        bail!(\"cannot check staged changes: git is unavailable\");\n    };\n    for root in roots {\n        let mut command = std::process::Command::new(git);\n        crate::git::sanitize_git_command(&mut command);\n        let output = command\n            .arg(\"-C\")\n            .arg(&root)\n            .args([\n                \"-c\",\n                \"core.fsmonitor=false\",\n                \"diff\",\n                \"--cached\",\n                \"--name-only\",\n                \"-z\",\n                \"--no-renames\",\n                \"--no-ext-diff\",\n                \"--no-textconv\",\n                \"--\",","sourceCodeStart":829,"sourceCodeEnd":865,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/sync/apply.rs#L829-L865","documentation":"staged_paths shells out to git (`git diff --name-only --staged`) to detect files staged for commit so they can be skipped during apply. If no git binary can be located via plumbing_binary(), staged-change detection is impossible and the operation fails rather than risking overwrite of staged work.","triggerScenarios":"Running a pull/apply when `git` is not installed or not discoverable on PATH (git unavailable in the environment mise is managing).","commonSituations":"Minimal containers or CI images without git; broken PATH in a shell where mise runs; git removed after mise was set up.","solutions":["Install git (e.g. `apt-get install git`, `brew install git`) or fix PATH so `git` resolves.","Verify with `command -v git` in the same shell that runs mise.","If staged-change skipping is not needed, stage nothing and ensure the environment provides git on retry."],"exampleFix":"// before (PATH lacking git)\nmise pull\n// after\nexport PATH=\"/usr/bin:$PATH\"  # ensure git is reachable\nmise pull","handlingStrategy":"fallback","validationCode":"if which(\"git\").is_err() {\n    // git unavailable: install or fix PATH before pulling\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = pull() {\n    if e.to_string().contains(\"git is unavailable\") {\n        // install git or correct PATH, then retry\n    }\n}","preventionTips":["Ensure git is installed in every environment running mise","Keep /usr/bin and mise's PATH intact in minimal containers","Check `command -v git` in shell profiles that mutate PATH"],"tags":["git","environment","dependency","path"],"backgroundTag":"missing-dependency","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}