Skip to content
LatchkeyLatchkey home

git merge-base Command: Find Common Ancestor in CI

git merge-base finds the commit where two branches diverged, their best common ancestor.

Change-aware CI needs to diff a PR against the point it branched from, not against the tip of the target branch. merge-base computes exactly that fork point.

Common flags

  • <a> <b> - print the best common ancestor of two commits
  • --fork-point <ref> - find where the current branch forked, using reflog data
  • --is-ancestor <a> <b> - exit zero if A is an ancestor of B (a test, no output)
  • --all - print all best common ancestors when several exist
  • --octopus - common ancestor for more than two commits

Example

shell
# Diff a PR against the point it diverged from main
BASE="$(git merge-base origin/main HEAD)"
git diff --name-only "${BASE}...HEAD"

In CI

Computing the merge-base is the correct way to scope a PR diff; using origin/main directly includes unrelated commits merged after the branch was cut. This requires enough history to reach the fork point, so use fetch-depth: 0 (or a deepened fetch) on PR builds.

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Key takeaways

  • git merge-base finds the true PR fork point for accurate changed-files diffs.
  • --is-ancestor is a clean boolean test for "is this commit reachable".
  • It needs history back to the divergence, so PR builds want fetch-depth 0.

Frequently asked questions

git merge-base Command: Find Common Ancestor in CI?
Change-aware CI needs to diff a PR against the point it branched from, not against the tip of the target branch. merge-base computes exactly that fork point.
In CI?
Computing the merge-base is the correct way to scope a PR diff; using origin/main directly includes unrelated commits merged after the branch was cut. This requires enough history to reach the fork point, so use fetch-depth: 0 (or a deepened fetch) on PR builds.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card