{"record":{"id":"35c2bb55a0769f6e","repo":"nikivdev/code","slug":"git-config-global-failed","errorCode":null,"errorMessage":"git config --global {} failed","messagePattern":"git config --global (.+?) failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/push_hook.rs","lineNumber":194,"sourceCode":"        .context(\"failed to read global core.hooksPath\")?;\n    if !output.status.success() {\n        return Ok(None);\n    }\n\n    let value = String::from_utf8_lossy(&output.stdout).trim().to_string();\n    if value.is_empty() {\n        return Ok(None);\n    }\n    Ok(Some(config::expand_path(&value)))\n}\n\nfn git_config_global_set(key: &str, value: &Path) -> Result<()> {\n    let status = Command::new(\"git\")\n        .args([\"config\", \"--global\", key, &value.to_string_lossy()])\n        .status()\n        .with_context(|| format!(\"failed to set git config {key}\"))?;\n    if !status.success() {\n        bail!(\"git config --global {} failed\", key);\n    }\n    Ok(())\n}\n\nfn git_config_global_unset(key: &str) -> Result<()> {\n    let status = Command::new(\"git\")\n        .args([\"config\", \"--global\", \"--unset\", key])\n        .status()\n        .with_context(|| format!(\"failed to unset git config {key}\"))?;\n    if !status.success() {\n        bail!(\"git config --global --unset {} failed\", key);\n    }\n    Ok(())\n}\n\nfn resolve_repo_root() -> Result<PathBuf> {\n    let output = Command::new(\"git\")\n        .args([\"rev-parse\", \"--show-toplevel\"])","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/push_hook.rs#L176-L212","documentation":"`git_config_global_set` runs `git config --global <key> <value>` and checks the exit status; when git exits non-zero it bails with this message. The `with_context` above catches spawn failures, so this error specifically means git ran but the config write was rejected.","triggerScenarios":"Calling `install_hooks` (via `git_config_global_set(\"core.hooksPath\", ...)`) when the global git config is unwritable or git rejects the operation: no HOME set, $HOME/.gitconfig or ~/.config/git/config unreadable/corrupt, permission denied on the config file, or invalid config include paths.","commonSituations":"CI containers running as a different user with no writable $HOME; read-only home directories; a locked or root-owned .gitconfig; malformed [include] directives in the global config causing git to fail.","solutions":["Verify `git config --global core.hooksPath /tmp/x` works manually to see git's real error","Ensure $HOME is set and writable (`echo $HOME`, `touch ~/.gitconfig`)","Fix or remove a corrupt/unreadable global config file (~/.gitconfig or ~/.config/git/config)","Check permissions: `ls -l ~/.gitconfig`; chown/chmod if it is root-owned","If HOME is unset (CI/systemd), set HOME or use `git config --file` explicitly"],"exampleFix":"// before: CI step with no HOME\ncargo run -- push hooks install   # git config --global core.hooksPath failed\n// after\nenv:\n  HOME: /home/ci\ncargo run -- push hooks install","handlingStrategy":"try-catch","validationCode":"// preflight: ensure global git config is writable\nlet home = std::env::var(\"HOME\").map(std::path::PathBuf::from)?;\nlet cfg = home.join(\".gitconfig\");\nif let Some(dir) = cfg.parent() {\n    assert!(dir.exists(), \"HOME dir missing: {}\", dir.display());\n}\nlet probe = std::process::Command::new(\"git\")\n    .args([\"config\", \"--global\", \"--list\"])\n    .status()?;\nassert!(probe.success(), \"git global config unreadable/broken\");","typeGuard":null,"tryCatchPattern":"match install_hooks() {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"git config --global\") => {\n        eprintln!(\"fix global git config (HOME writable, no corrupt [include]) and retry: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Ensure $HOME is set and writable before running in CI/containers","Keep ~/.gitconfig free of broken [include] paths","Run `git config --global --list` as a smoke test in setup scripts","Avoid running installs as root with a read-only home"],"tags":["git","config","subprocess","exit-status"],"backgroundTag":"git-config-write-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}