can1357/oh-my-pi · error · Error
merge conflict in {} file(s)
Error message
merge conflict in {} file(s) What it means
Error::Conflict is raised when a merge-style operation (cherry-pick, stash pop, 3-way apply) hits conflicting changes. The error carries the list of worktree-relative paths left in a conflicted state so callers can present resolution UI or abort programmatically.
Source
Thrown at crates/pi-vcs/src/error.rs:49
#[error("object not found: {spec}")]
ObjectNotFound {
/// The revision or object spec as given by the caller.
spec: String,
},
/// Cherry-picking `sha` produced an empty commit (already applied or
/// auto-resolved to HEAD). Callers should skip and continue the range —
/// replaces the historical `/the previous cherry-pick is now empty/` stderr
/// regex.
#[error("cherry-pick of {sha} is empty")]
EmptyCherryPick {
/// The commit that collapsed to a no-op.
sha: String,
},
/// A merge-style operation (cherry-pick, stash pop, 3-way apply) hit
/// conflicting changes.
#[error("merge conflict in {} file(s)", paths.len())]
Conflict {
/// Worktree-relative paths left in a conflicted state.
paths: Vec<String>,
},
/// A patch did not apply (context mismatch, missing file, malformed input).
#[error("patch does not apply: {message}")]
PatchFailed {
/// Human-readable reason, including the offending path when known.
message: String,
},
/// A CLI-backed operation (push/fetch/clone, reftable fallback) exited
/// non-zero. Carries the captured streams for user-facing error surfaces.
#[error("{}", crate::error::cli_message(command, *exit_code, stdout, stderr))]
Cli {
/// Rendered command line (`git push --no-follow-tags …`).
command: String,View on GitHub (pinned to 9690622007)
Solutions
- Inspect each path in `paths`, resolve conflict markers by hand (or a merge tool), then `git add` the files and continue the operation.
- Abort cleanly if unresolvable: `git cherry-pick --abort` / `git merge --abort` (or the library's abort API) to restore pre-operation state.
- Rebase the target branch onto its base first to reduce divergence, then retry the operation.
- Use a 3-way apply with a better base ref if the patch context drifted only slightly.
Example fix
// before
repo.cherry_pick("abc123")?; // surfaces raw conflict
// after
match repo.cherry_pick("abc123") {
Err(Error::Conflict { paths, .. }) => {
eprintln!("resolve these files first: {paths:?}");
repo.abort_cherry_pick()?;
}
Err(e) => return Err(e),
Ok(()) => {}
} Defensive patterns
Strategy: try-catch
Type guard
fn is_conflict(err: &pi_vcs::Error) -> Option<&[String]> {
match err {
pi_vcs::Error::Conflict { paths } => Some(paths),
_ => None,
}
} Try / catch
match repo.cherry_pick(sha) {
Err(pi_vcs::Error::Conflict { paths, .. }) => {
for p in &paths { eprintln!("conflict marker cleanup needed in {p}"); }
repo.abort_cherry_pick()?; // restore pre-operation state
}
other => other?,
} Prevention
- Rebase the target branch onto the base before merge-style operations to minimize divergence.
- Keep stashes short-lived; pop them right after creation or drop them after a rebase.
- Regenerate patches from a recent base rather than reusing old diff files.
- Always provide an abort/cleanup path when invoking operations that can conflict.
When it happens
Trigger: Cherry-pick/stash-pop/apply where the incoming change touches lines overlapping different content already in HEAD: e.g. applying a patch built against an old base, popping a stash onto a rebased branch, picking a commit into a heavily diverged branch.
Common situations: Long-lived branches diverging from main, stashes created before a rebase, automated backports after the file was refactored, parallel edits to the same lines by two developers.
Related errors
- cherry-pick of {sha} is empty
- not a repository: {path}
- reference not found: {name}
- object not found: {spec}
- patch does not apply: {message}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/a711a4bcb30b18aa.
Report an issue: GitHub.