{"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":1001,"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":983,"sourceCodeEnd":1019,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/sync/apply.rs#L983-L1019","documentation":"Before applying a pull, staged_paths asks git (the plumbing binary resolved by crate::git::plumbing_binary) which paths in the work tree are staged, so it can skip or handle them. If no git binary can be located on the system, mise cannot even check for staged changes and bails with this error instead of guessing. The pull is aborted because applying history over unknown staged state could destroy user work.","triggerScenarios":"`mise dot sync` (pull) runs on a machine where the git plumbing binary cannot be found: git is not installed, not on PATH, or the configured/plumbing binary path is invalid.","commonSituations":"Minimal containers or CI images without git; a broken PATH in the environment running mise; a mise install where the git lookup setting points at a missing binary.","solutions":["Install git (e.g. `apt install git`, `brew install git`) or fix PATH so the git binary is findable.","Verify with `which git` / `git --version` in the same shell that runs mise.","If mise is configured with a custom git binary path, correct or remove that configuration.","Commit or note your staged changes manually, then retry the sync once git is available."],"exampleFix":"// before\n$ mise dot sync   # git not installed in container\nerror: cannot check staged changes: git is unavailable\n// after\n$ apt-get install -y git\n$ mise dot sync   # succeeds","handlingStrategy":"fallback","validationCode":"command -v git >/dev/null 2>&1 || { echo 'git required for mise dot sync'; exit 1; }","typeGuard":null,"tryCatchPattern":"if err.contains('git is unavailable') {\n    // fall back: install git or skip sync with a warning\n}","preventionTips":["Ensure git is installed in containers/CI images that run mise sync.","Keep git on PATH for non-interactive shells (CI, cron).","Pin git in your devcontainer/Dockerfile."],"tags":["git","missing-dependency","environment","sync"],"backgroundTag":"missing-dependency","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}