{"record":{"id":"1b27d8bce6c7b094","repo":"jdx/mise","slug":"git-c-failed","errorCode":null,"errorMessage":"git -C {} {} failed: {}","messagePattern":"git -C (.+?) (.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/repos.rs","lineNumber":728,"sourceCode":"\nfn pull_ref_for(git_ref: &str) -> &str {\n    git_ref.strip_prefix(\"refs/heads/\").unwrap_or(git_ref)\n}\n\nfn git_output(path: &Path, args: &[&str]) -> Result<String> {\n    let safe = format!(\"safe.directory={}\", path.display());\n    let output = Command::new(\"git\")\n        .arg(\"-C\")\n        .arg(path)\n        .arg(\"-c\")\n        .arg(safe)\n        .arg(\"-c\")\n        .arg(\"core.autocrlf=false\")\n        .args(args)\n        .output()\n        .map_err(|err| eyre!(\"git failed: {err:#}\"))?;\n    if !output.status.success() {\n        bail!(\n            \"git -C {} {} failed: {}\",\n            path.display(),\n            shell_words::join(args),\n            String::from_utf8_lossy(&output.stderr).trim()\n        );\n    }\n    Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())\n}\n\nfn git_success(path: &Path, args: &[&str]) -> Result<bool> {\n    let safe = format!(\"safe.directory={}\", path.display());\n    let status = Command::new(\"git\")\n        .arg(\"-C\")\n        .arg(path)\n        .arg(\"-c\")\n        .arg(safe)\n        .arg(\"-c\")\n        .arg(\"core.autocrlf=false\")","sourceCodeStart":710,"sourceCodeEnd":746,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/repos.rs#L710-L746","documentation":"The repos subsystem's `git_output` helper runs `git -C <path> <args>` and captures output. If git exits non-zero, the error wraps the path, the shell-quoted arguments, and git's trimmed stderr. This is the standard wrapper failure for all read-only git queries (status, current ref, sha, local refs) used by repos status/update.","triggerScenarios":"Any repos command calling status_one, is_git_repo, is_clean, current_ref, current_sha, or local_ref_sha where git exits non-zero — e.g. querying a ref/sha that doesn't exist, a corrupt repo, or a path that is no longer a git repo mid-operation.","commonSituations":"Pinned ref/tag deleted from origin and locally; git objects corrupted; repo directory replaced by a non-git folder; permission problems on .git.","solutions":["Read the quoted git command and stderr in the message to see git's own explanation.","Run the exact quoted `git -C <path> <args>` command by hand to reproduce and debug.","If a pinned ref is missing, verify it exists (`git ls-remote origin <ref>`) and fix the ref in your repos config.","Repair or re-clone a corrupt repo; check .git permissions."],"exampleFix":"// config pinning a nonexistent tag\n[[repos]]\npath = \"~/code/myrepo\"\nref = \"v9.9.9\"\n// after: fix the ref to an existing tag\n[[repos]]\npath = \"~/code/myrepo\"\nref = \"v1.2.0\"","handlingStrategy":"try-catch","validationCode":"# Verify the repo is a valid git repo and pinned refs exist before running repos commands\ngit -C \"$repo\" rev-parse --is-inside-work-tree || echo \"not a git repo\"\ngit -C \"$repo\" cat-file -e \"$ref\" 2>/dev/null || echo \"ref missing: $ref\"","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"git -C\") => {\n        eprintln!(\"git query failed: {e:#}; check the quoted command and stderr\");\n    }\n    r => r?,\n}","preventionTips":["Verify pinned refs/tags exist on the remote before pinning them.","Don't replace or delete .git in mise-managed repos; re-clone via mise instead.","Keep git healthy: run git fsck if you suspect corruption.","Check filesystem permissions on repo directories."],"tags":["git","subprocess","stderr"],"backgroundTag":"git-command-failed","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"}