alibaba/open-code-review · error
cannot find merge-base between
Error message
cannot find merge-base between %s and %s
What it means
In ModeRange, GetDiff first computes the merge-base of p.from and p.to via MergeBase; if git returns no merge-base (empty string), the range diff is meaningless and this error is returned. It means the two revisions share no common ancestor, so 'from..to' style comparison cannot be performed.
Solutions
- Check both refs exist (git rev-parse <from> <to>) and are spelled correctly
- Use refs that share history, or unshallow the clone (git fetch --unshallow)
- Switch the diff mode to a workspace or commit diff instead of a range diff
- Verify ancestry with git merge-base <from> <to> before invoking
Example fix
// before
base := p.MergeBase(ctx); if base == "" { return nil, ... } // unrelated refs
// after
// pick a common ancestor
params.from = "main"; params.to = "feature" // both on shared history
base := p.MergeBase(ctx); if base == "" { return nil, ... } Defensive patterns
Strategy: validation
Validate before calling
func haveMergeBase(ctx context.Context, dir, from, to string) bool {
out, err := exec.CommandContext(ctx, "git", "-C", dir, "merge-base", from, to).Output()
return err == nil && len(bytes.TrimSpace(out)) > 0
} Try / catch
d, err := differ.GetDiff(ctx, p)
if err != nil && strings.Contains(err.Error(), "cannot find merge-base") {
// fall back to two-dot compare or workspace diff
} Prevention
- Unshallow CI clones (fetch-depth: 0) so merge-bases resolve
- Verify both refs share history before requesting a range diff
- Sanitize/refuse user-supplied refs that fail git rev-parse
When it happens
Trigger: Calling GetDiff on a params with mode=ModeRange where from and to are unrelated histories (e.g. two orphan branches), or where a revision name is invalid enough that git merge-base silently returns nothing.
Common situations: Comparing a fresh orphan branch against main; typo'd ref names; comparing across repos or after history rewrites that severed ancestry; CI shallow clones missing shared history.
Related errors
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/63fba6fd4717072e.
Report an issue: GitHub.
Appendix: source
Thrown at internal/diff/git.go:181
// MergeBase returns the computed merge-base commit hash for range mode.
func (p *Provider) MergeBase(ctx context.Context) string {
if p.mode != ModeRange || p.mergeBase != "" {
return p.mergeBase
}
p.mergeBase = p.computeMergeBase(ctx, p.from, p.to)
return p.mergeBase
}
// GetDiff returns all changes as parsed model.Diff structs.
func (p *Provider) GetDiff(ctx context.Context) ([]model.Diff, error) {
var combined strings.Builder
switch p.mode {
case ModeRange:
base := p.MergeBase(ctx)
if base == "" {
return nil, fmt.Errorf("cannot find merge-base between %s and %s", p.from, p.to)
}
out, stderr, err := p.runGitSplit(ctx, "-c", "core.quotepath=false", "diff", "--no-ext-diff", "--no-textconv", "--find-renames", "--src-prefix=a/", "--dst-prefix=b/", "--no-color", "-U"+fmt.Sprint(DiffContextLines), "--end-of-options", base, p.to, "--")
if err != nil {
return nil, gitFailure("git diff", stderr, err)
}
combined.WriteString(out)
case ModeCommit:
// --diff-merges=first-parent: for merge commits, plain `git show`
// emits a combined diff ("diff --cc"), which ParseDiffText cannot
// parse — the commit would silently yield zero reviewable diffs.
// Diffs against the first parent instead, in regular unified format.
out, stderr, err := p.runGitSplit(ctx, "-c", "core.quotepath=false", "show", "--no-ext-diff", "--no-textconv", "--find-renames", "--src-prefix=a/", "--dst-prefix=b/", "--no-color", "--diff-merges=first-parent", "-U"+fmt.Sprint(DiffContextLines), "--end-of-options", p.commit)
if err != nil {
return nil, gitFailure("git show", stderr, err)
}
combined.WriteString(out)
View on GitHub (pinned to 5cf97d0d15)