{"record":{"id":"eaa07019eeaa26a6","repo":"nikivdev/code","slug":"git-index-lock-detected-during-merge-remove-stale","errorCode":null,"errorMessage":"Git index lock detected during merge. Remove stale .git/index.lock (if no git process is running) and re-run.","messagePattern":"Git index lock detected during merge\\. Remove stale \\.git/index\\.lock \\(if no git process is running\\) and re-run\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sync.rs","lineNumber":4044,"sourceCode":"        recorder.record(stage, format!(\"already up to date with {}\", remote_ref));\n        return Ok(());\n    }\n\n    sync_progressln!(\"Merging {} commits from {}...\", behind, remote_ref);\n    recorder.record(\n        stage,\n        format!(\"merging {} commits from {}\", behind, remote_ref),\n    );\n\n    let ff_only_output = git_run_output_in(repo_root, &[\"merge\", \"--ff-only\", &remote_ref])?;\n    if ff_only_output.status.success() {\n        recorder.record(stage, format!(\"fast-forwarded to {}\", remote_ref));\n        return Ok(());\n    }\n\n    let ff_only_detail = git_output_text(&ff_only_output);\n    if is_git_index_lock_error(&ff_only_detail) {\n        bail!(\n            \"Git index lock detected during merge. Remove stale .git/index.lock (if no git process is running) and re-run.\"\n        );\n    }\n    if !is_expected_ff_only_merge_failure(&ff_only_detail) {\n        bail!(\n            \"git merge --ff-only {} failed: {}\",\n            remote_ref,\n            ff_only_detail\n        );\n    }\n\n    let merge_output = git_run_output_in(repo_root, &[\"merge\", &remote_ref, \"--no-edit\"])?;\n    if merge_output.status.success() {\n        recorder.record(stage, format!(\"merged {} with commit\", remote_ref));\n        return Ok(());\n    }\n    let merge_detail = git_output_text(&merge_output);\n    if is_git_index_lock_error(&merge_detail) {","sourceCodeStart":4026,"sourceCodeEnd":4062,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/sync.rs#L4026-L4062","documentation":"Thrown in src/sync.rs when `git merge --ff-only <remote_ref>` fails and its output matches `is_git_index_lock_error`. Git refuses to run because `.git/index.lock` exists, usually a stale lock left by a crashed or concurrent git process. The message instructs removing the lock only when no git process is running.","triggerScenarios":"During sync's fast-forward stage, the ff-only merge exits with an 'Unable to create ... index.lock: File exists' style error. Commonly after a killed git process, an IDE/git GUI holding the index, or two syncs running concurrently.","commonSituations":"A previous sync was interrupted (Ctrl-C, crash, laptop sleep); a background IDE (VS Code git integration) holds the index; running multiple f sync instances in parallel terminals.","solutions":["Confirm no git process is running: `ps aux | grep git` (also check IDE git integrations).","Remove the stale lock: `rm .git/index.lock`, then re-run sync.","Close IDE/git GUI tools that may hold the index, then retry.","If the lock reappears, investigate what is spawning concurrent git operations (hooks, cron jobs, parallel syncs)."],"exampleFix":"// before\nf sync\n// error: Git index lock detected during merge...\n\n// after\nps aux | grep '[g]it'        # verify nothing is running\nrm -f .git/index.lock\nf sync","handlingStrategy":"validation","validationCode":"import std::path::Path;\nif Path::new(\".git/index.lock\").exists() {\n    eprintln!(\".git/index.lock exists; ensure no git process is running, then remove it.\");\n    std::process::exit(1);\n}","typeGuard":"fn index_lock_stale(repo_root: &Path) -> bool {\n    repo_root.join(\".git/index.lock\").exists()\n}","tryCatchPattern":"match sync::run(&repo_root, &cmd) {\n    Err(e) if e.to_string().contains(\"index.lock\") => {\n        eprintln!(\"Stale git index lock. Verify no git process, then: rm .git/index.lock\");\n    }\n    other => other,\n}","preventionTips":["Avoid killing git processes mid-operation; let merges/fetches finish.","Run only one sync per working copy at a time; serialize automation jobs.","Watch out for IDE git integrations (VS Code etc.) holding the index during sync.","If crashes recur, clean stale locks as part of environment startup (after checking ps)."],"tags":["git","merge","index-lock","stale-lock","fast-forward"],"backgroundTag":"git-index-lock","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}