nikivdev/code · error
git config --global --unset {} failed
Error message
git config --global --unset {} failed What it means
`git_config_global_unset` runs `git config --global --unset core.hooksPath` and bails when git exits non-zero. The most common non-zero case is git's exit code 5: the key is not set, so there is nothing to unset.
Source
Thrown at src/push_hook.rs:205
fn git_config_global_set(key: &str, value: &Path) -> Result<()> {
let status = Command::new("git")
.args(["config", "--global", key, &value.to_string_lossy()])
.status()
.with_context(|| format!("failed to set git config {key}"))?;
if !status.success() {
bail!("git config --global {} failed", key);
}
Ok(())
}
fn git_config_global_unset(key: &str) -> Result<()> {
let status = Command::new("git")
.args(["config", "--global", "--unset", key])
.status()
.with_context(|| format!("failed to unset git config {key}"))?;
if !status.success() {
bail!("git config --global --unset {} failed", key);
}
Ok(())
}
fn resolve_repo_root() -> Result<PathBuf> {
let output = Command::new("git")
.args(["rev-parse", "--show-toplevel"])
.output()
.context("failed to resolve git repo root")?;
if output.status.success() {
let value = String::from_utf8_lossy(&output.stdout).trim().to_string();
if !value.is_empty() {
return Ok(PathBuf::from(value));
}
}
env::current_dir().context("failed to resolve current directory")
}View on GitHub (pinned to a747e741ae)
Solutions
- Check `git config --global --get core.hooksPath`; if unset, the goal is already achieved and the error can be ignored
- Verify ~/.gitconfig is writable (`ls -l ~/.gitconfig`) and fix permissions
- Wrap the uninstall call to tolerate git exit code 5 (key not present)
- Avoid running uninstall concurrently; serialize cleanup steps in CI
Example fix
// before: unconditional cleanup step fails on second run - run: f push hooks uninstall // after: tolerate already-unset - run: f push hooks uninstall || git config --global --get core.hooksPath | grep -q . && exit 1 || exit 0
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: check whether the key is set before unsetting
let out = std::process::Command::new("git")
.args(["config", "--global", "--get", "core.hooksPath"])
.output()?;
let is_set = out.status.success() && !out.stdout.is_empty();
if !is_set { eprintln!("core.hooksPath already unset; skipping uninstall"); } Try / catch
match uninstall_hooks() {
Ok(()) => {},
Err(e) if e.to_string().contains("--unset") => {
// often just 'key not set' (git exit code 5) — treat as already-clean
eprintln!("unset failed (possibly already unset): {e}");
}
Err(e) => return Err(e),
} Prevention
- Make uninstall idempotent: check --get before --unset
- Don't run uninstall concurrently from multiple CI jobs
- Ignore git exit code 5 (key absent) as a success condition in wrappers
- Verify config file permissions in teardown scripts
When it happens
Trigger: Calling `uninstall_hooks` when the config pointed at by current_hooks_path matches but `git config --global --unset core.hooksPath` fails — typically because the key was already removed (race or a second uninstall run), or the global config is unwritable/corrupt.
Common situations: Running uninstall twice in a row or in parallel; uninstalling from a second shell after hooksPath was manually unset; CI cleanup steps running concurrently; read-only HOME during teardown.
Related errors
- git config --global {} failed
- git config --global --unset-all {} failed
- Lin.app is not running
- failed to stash working tree: {}
- git status failed with {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/a98d77a995db9595.
Report an issue: GitHub.