affaan-m/ECC · error · anyhow::Error

Worktree has uncommitted changes; commit or discard them…

Error message

Worktree {} has uncommitted changes; commit or discard them before rebasing

What it means

`rebase_onto_base` refuses to run when the worktree has uncommitted changes, detected via `has_uncommitted_changes`. Rebasing with a dirty tree would lose or interleave edits, so the library bails with an explicit guard error naming the branch. It is a deliberate precondition check, not a git failure.

Solutions

  1. Commit the changes in the worktree: 'git add -A && git commit -m "wip before rebase"'
  2. Discard unwanted changes: 'git restore .' (tracked) or 'git clean -fd' (untracked)
  3. Stash them: 'git stash' then rebase, then 'git stash pop'
  4. Fix the build process that is dirtying files (e.g. generated lockfiles) so the tree stays clean

Example fix

// before: rebase with dirty tree -> error
rebase_onto_base(&wt)?;
// after: ensure clean tree first
anyhow::ensure!(
    !has_uncommitted_changes(&wt)?,
    "commit or stash changes in worktree {} first",
    wt.branch
);
rebase_onto_base(&wt)?;
Defensive patterns

Strategy: validation

Validate before calling

let status = Command::new("git")
    .args(["status", "--porcelain"])
    .current_dir(&wt.path)
    .output()?;
let clean = status.stdout.is_empty();
anyhow::ensure!(clean, "commit or stash changes in worktree {} first", wt.branch);

Prevention

When it happens

Trigger: Calling rebase_onto_base on a WorktreeInfo whose working tree contains modified, staged, or untracked-but-relevant files that make the tree dirty.

Common situations: A developer edited files inside the worktree but forgot to commit before clicking rebase; a build artifact or lockfile changed on disk; an editor auto-saved a file mid-session.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/c90e32264fc0d419. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/worktree/mod.rs:915

        anyhow::bail!("git merge failed: {stderr}");
    }

    let merged_output = format!(
        "{}\n{}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );

    Ok(MergeOutcome {
        branch: worktree.branch.clone(),
        base_branch: worktree.base_branch.clone(),
        already_up_to_date: merged_output.contains("Already up to date."),
    })
}

pub fn rebase_onto_base(worktree: &WorktreeInfo) -> Result<RebaseOutcome> {
    if has_uncommitted_changes(worktree)? {
        anyhow::bail!(
            "Worktree {} has uncommitted changes; commit or discard them before rebasing",
            worktree.branch
        );
    }

    let repo_root = base_checkout_path(worktree)?;
    let before_head = branch_head_oid_in_repo(&repo_root, &worktree.branch)?;
    let output = Command::new("git")
        .arg("-C")
        .arg(&worktree.path)
        .args(["rebase", &worktree.base_branch])
        .output()
        .context("Failed to rebase worktree branch onto base")?;

    if !output.status.success() {
        let abort_output = Command::new("git")
            .arg("-C")
            .arg(&worktree.path)

View on GitHub (pinned to 8321021c54)