jdx/mise · error

multiple merge bases require explicit Git reconciliation bef

Error message

multiple merge bases require explicit Git reconciliation before applying enrollment

What it means

When applying an enrollment (first-time adoption of a remote setup), mise merges the incoming remote manifest with the local one via their merge base. Git reports multiple merge bases; the three-way manifest merge cannot pick a single ancestor, so mise refuses to guess and demands explicit Git reconciliation first. This prevents silently mis-merging tracking metadata during adoption.

Source

Thrown at src/system/history/sync/run.rs:975

pub(super) fn incoming_tracking(
    repo: &crate::system::history::shadow::HistoryRepo,
    tracked: &TrackedSet,
) -> Result<TrackedSet> {
    use crate::system::history::manifest::Manifest;
    let heads = super::graph::Heads::read(repo)?;
    let Some(remote) = &heads.remote else {
        return Ok(tracked.clone());
    };
    let remote = Manifest::read(repo, remote)?
        .ok_or_else(|| eyre::eyre!("setup repository has no enrollment metadata"))?;
    let manifest = match (&heads.local, &heads.base) {
        (None, _) => remote,
        (Some(local), Some(base)) => Manifest::merge(
            &Manifest::read(repo, base)?.unwrap_or_default(),
            &Manifest::read(repo, local)?.unwrap_or_default(),
            &remote,
        )?,
        (Some(_), None) => bail!(
            "multiple merge bases require explicit Git reconciliation before applying enrollment"
        ),
    };
    let mut incoming = manifest.tracking()?;
    incoming.required_sources = tracked.required_sources.clone();
    incoming.invalid = tracked.invalid.clone();
    Ok(incoming)
}

/// Complete-tree changes outside active native files still need adoption:
/// enrollment, inactive variants, and ordinary repository documentation.
pub(super) fn incoming_repository_tree(
    repo: &crate::system::history::shadow::HistoryRepo,
    tracked: &TrackedSet,
) -> Result<Option<String>> {
    let heads = super::graph::Heads::read(repo)?;
    let (Some(local), Some(remote)) = (&heads.local, &heads.remote) else {
        return Ok(None);

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Open the underlying history repository with git and reconcile manually (merge/cherry-pick to a single head), then retry enrollment
  2. Reset the local history head to a single unambiguous commit before enrolling
  3. If the local history is disposable, remove it and enroll fresh from the remote
Defensive patterns

Strategy: fallback

Validate before calling

git merge-base --all <local-history-head> <remote-history-head>   # expect exactly one base

Prevention

When it happens

Trigger: `incoming_tracking` (called from `prepare` during enrollment) sees `(Some(local), None)` — a local head exists but no unique merge base could be determined because the history has criss-cross merges / multiple bases.

Common situations: Enrolling onto a machine whose history repository was imported from divergent sources; a cloned history ref with criss-cross branch merges; manually rewritten history removing the common ancestor.

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 jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/a178a70bf973480e. Report an issue: GitHub.