{"record":{"id":"6033880ad60bb454","repo":"GitoxideLabs/gitoxide","slug":"no-base-found-for-first-and-others","errorCode":null,"errorMessage":"No base found for {first} and {others}","messagePattern":"No base found for (.+?) and (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"gitoxide-core/src/repository/merge_base.rs","lineNumber":26,"sourceCode":"    others: Vec<String>,\n    mut out: impl std::io::Write,\n    format: OutputFormat,\n) -> anyhow::Result<()> {\n    if format != OutputFormat::Human {\n        bail!(\"Only 'human' format is currently supported\");\n    }\n    repo.object_cache_size_if_unset(50 * 1024 * 1024);\n    let first_id = commit_id(&repo, first.as_str())?;\n    let other_ids: Vec<_> = others\n        .iter()\n        .map(|other| commit_id(&repo, other.as_str()))\n        .collect::<Result<_, _>>()?;\n\n    let cache = repo.commit_graph_if_enabled()?;\n    let mut graph = repo.revision_graph(cache.as_ref());\n    let bases = repo.merge_bases_many_with_graph(first_id, &other_ids, &mut graph)?;\n    if bases.is_empty() {\n        bail!(\"No base found for {first} and {others}\", others = others.join(\", \"))\n    }\n    for id in bases {\n        writeln!(&mut out, \"{id}\")?;\n    }\n    Ok(())\n}\n\nfn commit_id(repo: &gix::Repository, revspec: &str) -> anyhow::Result<gix::ObjectId> {\n    Ok(repo.rev_parse_single(revspec)?.object()?.peel_to_commit()?.id)\n}\n","sourceCodeStart":8,"sourceCodeEnd":37,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gitoxide-core/src/repository/merge_base.rs#L8-L37","documentation":"`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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Verify both commits exist and share history: `git log --oneline <first>..<other>` should not show every commit as unrelated.","If histories are intentionally unrelated, handle the empty-base case explicitly instead of merging with a base.","Unshallow the clone (`git fetch --unshallow`) if ancestry was truncated.","Check for typos in the ref names/ids passed as `first` and `others`."],"exampleFix":"// caller-side guard\nlet bases = repo.merge_bases_many_with_graph(first_id, &other_ids, &mut graph)?;\nif bases.is_empty() {\n    eprintln!(\"no merge base: unrelated histories? skipping merge\");\n    return Ok(()); // or use an empty-tree base if that is your policy\n}","handlingStrategy":"validation","validationCode":"let bases = repo.merge_bases_many_with_graph(first_id, &other_ids, &mut graph)?;\nif bases.is_empty() {\n    eprintln!(\"unrelated histories: {first:?} vs others\");\n    return Ok(()); // handle explicitly\n}","typeGuard":null,"tryCatchPattern":"match merge_base(...) {\n    Err(e) if e.to_string().contains(\"No base found\") => handle_unrelated_histories(),\n    r => r?,\n}","preventionTips":["Verify shared ancestry exists before merging (e.g. diff/log between the refs).","Unshallow clones before computing merge bases.","Validate ref names/ids before passing them to the command."],"tags":["merge-base","git","graph","gitoxide"],"backgroundTag":"empty-result-set","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}