GitoxideLabs/gitoxide · error · anyhow::Error

No base found for and

Error message

No base found for {first} and {others}

What it means

`merge_base` computes merge bases via `merge_bases_many_with_graph`; if the returned set is empty there is no common ancestor between the given commits, so no merge base can be printed and the command bails, naming the first commit and all others.

Solutions

  1. Verify both commits exist and share history: `git log --oneline <first>..<other>` should not show every commit as unrelated.
  2. If histories are intentionally unrelated, handle the empty-base case explicitly instead of merging with a base.
  3. Unshallow the clone (`git fetch --unshallow`) if ancestry was truncated.
  4. Check for typos in the ref names/ids passed as `first` and `others`.

Example fix

// caller-side guard
let bases = repo.merge_bases_many_with_graph(first_id, &other_ids, &mut graph)?;
if bases.is_empty() {
    eprintln!("no merge base: unrelated histories? skipping merge");
    return Ok(()); // or use an empty-tree base if that is your policy
}
Defensive patterns

Strategy: validation

Validate before calling

let bases = repo.merge_bases_many_with_graph(first_id, &other_ids, &mut graph)?;
if bases.is_empty() {
    eprintln!("unrelated histories: {first:?} vs others");
    return Ok(()); // handle explicitly
}

Try / catch

match merge_base(...) {
    Err(e) if e.to_string().contains("No base found") => handle_unrelated_histories(),
    r => r?,
}

Prevention

When it happens

Trigger: Passing two or more commits with no common history (e.g. unrelated roots, an orphaned branch, or bogus/disconnected revisions in a freshly grafted repo).

Common situations: Merging/importing unrelated histories (common after scaffolding a repo separately); a typo or rewritten history replacing the expected shared ancestor; shallow clones missing the common ancestry.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/6033880ad60bb454. Report an issue: GitHub.

Appendix: source

Thrown at gitoxide-core/src/repository/merge_base.rs:26

    others: Vec<String>,
    mut out: impl std::io::Write,
    format: OutputFormat,
) -> anyhow::Result<()> {
    if format != OutputFormat::Human {
        bail!("Only 'human' format is currently supported");
    }
    repo.object_cache_size_if_unset(50 * 1024 * 1024);
    let first_id = commit_id(&repo, first.as_str())?;
    let other_ids: Vec<_> = others
        .iter()
        .map(|other| commit_id(&repo, other.as_str()))
        .collect::<Result<_, _>>()?;

    let cache = repo.commit_graph_if_enabled()?;
    let mut graph = repo.revision_graph(cache.as_ref());
    let bases = repo.merge_bases_many_with_graph(first_id, &other_ids, &mut graph)?;
    if bases.is_empty() {
        bail!("No base found for {first} and {others}", others = others.join(", "))
    }
    for id in bases {
        writeln!(&mut out, "{id}")?;
    }
    Ok(())
}

fn commit_id(repo: &gix::Repository, revspec: &str) -> anyhow::Result<gix::ObjectId> {
    Ok(repo.rev_parse_single(revspec)?.object()?.peel_to_commit()?.id)
}

View on GitHub (pinned to e73179060b)