{"record":{"id":"b352b8b48f06ee07","repo":"affaan-m/ECC","slug":"repository-root-has-uncommitted-changes-commit","errorCode":null,"errorMessage":"Repository root {} has uncommitted changes; commit or stash them before merging","messagePattern":"Repository root (.+?) has uncommitted changes; commit or stash them before merging","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/worktree/mod.rs","lineNumber":882,"sourceCode":"    if has_uncommitted_changes(worktree)? {\n        anyhow::bail!(\n            \"Worktree {} has uncommitted changes; commit or discard them before merging\",\n            worktree.branch\n        );\n    }\n\n    let repo_root = base_checkout_path(worktree)?;\n    let current_branch = get_current_branch(&repo_root)?;\n    if current_branch != worktree.base_branch {\n        anyhow::bail!(\n            \"Base branch {} is not checked out in repo root (currently {})\",\n            worktree.base_branch,\n            current_branch\n        );\n    }\n\n    if !git_status_short(&repo_root)?.is_empty() {\n        anyhow::bail!(\n            \"Repository root {} has uncommitted changes; commit or stash them before merging\",\n            repo_root.display()\n        );\n    }\n\n    let output = Command::new(\"git\")\n        .arg(\"-C\")\n        .arg(&repo_root)\n        .args([\"merge\", \"--no-edit\", &worktree.branch])\n        .output()\n        .context(\"Failed to merge worktree branch into base\")?;\n\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        anyhow::bail!(\"git merge failed: {stderr}\");\n    }\n\n    let merged_output = format!(","sourceCodeStart":864,"sourceCodeEnd":900,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/worktree/mod.rs#L864-L900","documentation":"merge_into_base also requires the repository root checkout itself to be clean. If `git status --short` in the root is non-empty, the library bails because a merge into the base would mix uncommitted root changes with the incoming merge.","triggerScenarios":"Calling merge_into_base while the repo root has modified, staged, or untracked files — the same dirty-tree condition as the worktree, but on the base checkout.","commonSituations":"Hotfix or WIP made directly in the root; build/test artifacts written into the root; pull left local modifications behind.","solutions":["Commit the root changes: `git -C <root> add -A && git commit`.","Or stash them: `git -C <root> stash` and retry the merge.","Clean untracked artifacts with `git -C <root> clean -fd` (after reviewing) or gitignore them.","Check `git -C <root> status --short` in your own code before calling merge_into_base.","Redirect root-level work into its own worktree so the base checkout stays clean."],"exampleFix":"// before\nmerge_into_base(&wt)?; // fails: dirty repo root\n// after\nlet root = base_checkout_path(&wt)?;\nCommand::new(\"git\").arg(\"-C\").arg(&root).args([\"stash\"]).status()?;\nmerge_into_base(&wt)?;","handlingStrategy":"validation","validationCode":"let root = base_checkout_path(&wt)?;\nif !git_status_short(&root)?.is_empty() {\n    eprintln!(\"root is dirty; commit or stash first\");\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = merge_into_base(&wt) {\n    if e.to_string().contains(\"Repository root\") {\n        // stash/commit root changes, then retry\n    } else { return Err(e); }\n}","preventionTips":["Do direct work in dedicated worktrees, never the base checkout","Gitignore build/test artifacts at the repo root","Run `git status --short` at root as a precheck","Stash or commit root changes before any merge operation"],"tags":["git","precondition","clean-tree"],"backgroundTag":"invalid-state-transition","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}