{"record":{"id":"ab54983124ee3432","repo":"affaan-m/ECC","slug":"readiness-summary","errorCode":null,"errorMessage":"readiness.summary","messagePattern":"readiness\\.summary","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/worktree/mod.rs","lineNumber":861,"sourceCode":"    } else {\n        Ok(WorktreeHealth::InProgress)\n    }\n}\n\npub fn has_uncommitted_changes(worktree: &WorktreeInfo) -> Result<bool> {\n    Ok(!git_status_short(&worktree.path)?.is_empty())\n}\n\npub fn has_staged_changes(worktree: &WorktreeInfo) -> Result<bool> {\n    Ok(git_status_entries(worktree)?\n        .iter()\n        .any(|entry| entry.staged))\n}\n\npub fn merge_into_base(worktree: &WorktreeInfo) -> Result<MergeOutcome> {\n    let readiness = merge_readiness(worktree)?;\n    if readiness.status == MergeReadinessStatus::Conflicted {\n        anyhow::bail!(readiness.summary);\n    }\n\n    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    }","sourceCodeStart":843,"sourceCodeEnd":879,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/worktree/mod.rs#L843-L879","documentation":"merge_into_base first calls merge_readiness; if the worktree branch is Conflicted, it aborts the merge with the readiness summary as the error message. The summary lists the conflicting files, so this error is the library's way of refusing to perform a merge that git would reject mid-flight.","triggerScenarios":"Calling merge_into_base for a worktree whose changes overlap with changes already on the base branch — merge_readiness detected staged conflict entries via merge-tree.","commonSituations":"Two worktrees edited the same lines; base branch advanced (e.g. after another feature merged) and now conflicts with this branch; long-lived branch that was never rebased.","solutions":["Read readiness.summary to see which files conflict.","Rebase the worktree branch onto the updated base: `git rebase <base_branch>` in the worktree.","Resolve conflicts, then retry merge_into_base.","Alternatively merge base into the branch first to resolve conflicts locally.","Call merge_readiness yourself before merging to present conflicts to the user instead of failing."],"exampleFix":"// before\nmerge_into_base(&wt)?; // fails when conflicted\n// after\nlet readiness = merge_readiness(&wt)?;\nanyhow::ensure!(readiness.status != MergeReadinessStatus::Conflicted, \"resolve conflicts first\");\nmerge_into_base(&wt)?;","handlingStrategy":"validation","validationCode":"let readiness = merge_readiness(&wt)?;\nif readiness.status == MergeReadinessStatus::Conflicted {\n    eprintln!(\"conflicts: {}\", readiness.summary);\n    return Ok(()); // or prompt the user\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = merge_into_base(&wt) {\n    eprintln!(\"merge blocked: {e}\"); // message is the conflict summary — show it to the user\n}","preventionTips":["Check merge_readiness before every merge_into_base call","Rebase branches onto base frequently to avoid drift","Surface readiness.summary in UI instead of attempting the merge","Keep branches short-lived"],"tags":["git","merge","conflict"],"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"}