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

git rebase failed

Error message

git rebase failed: {}{}

What it means

Raised by `rebase_onto_base` when `git rebase` onto the base branch exits non-zero. The message combines git's stdout and stderr plus an `abort_warning`, since the library aborts the failed rebase before surfacing it — most commonly this is a rebase conflict that could not be resolved automatically.

Solutions

  1. Read stdout/stderr in the message to find the conflicting commit; resolve manually with 'git rebase --continue' after fixing, or accept the library's auto-abort
  2. Rebase manually in the worktree: 'git rebase <base>', resolve conflicts per commit, then retry the tool
  3. If a commit is now empty, use 'git rebase --skip' or drop it from history
  4. Avoid repeated conflicts by squash-merging branch work back to base regularly
  5. If abort_warning indicates the rebase was aborted, verify with 'git status' that the branch is back at its pre-rebase HEAD before retrying

Example fix

// before: conflict fails silently until rebase_onto_base bails
rebase_onto_base(&wt)?;
// after: pre-check overlap
let overlap = Command::new("git")
    .args(["merge-tree", "--write-tree", &base, &wt.branch])
    .output()?;
anyhow::ensure!(overlap.status.success(), "rebase would conflict; resolve manually");
Defensive patterns

Strategy: try-catch

Validate before calling

let check = Command::new("git")
    .args(["merge-tree", "--write-tree", &base, &wt.branch])
    .current_dir(&wt.path)
    .output()?;
let rebase_clean = check.status.success();

Type guard

fn was_rebase_aborted(err: &anyhow::Error) -> bool {
    err.to_string().contains("aborted") || err.to_string().contains("CONFLICT")
}

Try / catch

match rebase_onto_base(&wt) {
    Ok(o) => o,
    Err(e) => {
        // library auto-aborts; verify branch is intact before retry
        let head = branch_head_oid_in_repo(&root, &wt.branch)?;
        eprintln!("rebase failed, branch {} at {}", wt.branch, head);
        Err(e)
    }
}

Prevention

When it happens

Trigger: Calling rebase_onto_base when the branch's commits conflict with the new base commits, a commit becomes empty during replay, or the rebase command itself fails (bad ref, detached state).

Common situations: Base branch advanced with overlapping changes; pick conflicts on generated files; empty commits after an earlier squash; rebase interrupted by an external process.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


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

Appendix: source

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

            .arg("-C")
            .arg(&worktree.path)
            .args(["rebase", "--abort"])
            .output()
            .context("Failed to abort unsuccessful rebase")?;
        let abort_warning = if abort_output.status.success() {
            String::new()
        } else {
            format!(
                " (rebase abort warning: {})",
                String::from_utf8_lossy(&abort_output.stderr).trim()
            )
        };
        let stderr = format!(
            "{}\n{}",
            String::from_utf8_lossy(&output.stdout),
            String::from_utf8_lossy(&output.stderr)
        );
        anyhow::bail!("git rebase failed: {}{}", stderr.trim(), abort_warning);
    }

    let after_head = branch_head_oid_in_repo(&repo_root, &worktree.branch)?;
    let rebase_output = format!(
        "{}\n{}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );

    Ok(RebaseOutcome {
        branch: worktree.branch.clone(),
        base_branch: worktree.base_branch.clone(),
        already_up_to_date: before_head == after_head || rebase_output.contains("up to date"),
    })
}

pub fn branch_head_oid(worktree: &WorktreeInfo, branch: &str) -> Result<String> {
    let repo_root = base_checkout_path(worktree)?;

View on GitHub (pinned to 8321021c54)