git merge-base --fork-point and --is-ancestor in CI
git merge-base A B prints the best common ancestor commit; --is-ancestor tests a relationship via exit code, and --fork-point uses the reflog to find where a branch diverged.
PR pipelines diff a branch against the point it forked from, not the current tip of main. merge-base computes that point. --is-ancestor gives a clean exit code to gate on, which is friendlier in scripts than parsing output.
What it does
git merge-base finds the commit where two histories last shared a common ancestor, the natural base for a three-dot diff. --is-ancestor A B exits 0 if A is an ancestor of B and 1 otherwise. --fork-point consults the target branch reflog to find the divergence point even after the upstream moved.
Common usage
BASE=$(git merge-base origin/main HEAD)
git diff "$BASE" HEAD --name-only
# gate: is this commit already on main?
git merge-base --is-ancestor HEAD origin/main && echo "already merged"
# divergence point accounting for rebased upstream
git merge-base --fork-point origin/main featureOptions
| Flag | What it does |
|---|---|
| (default) A B | Print the best common ancestor SHA |
| --is-ancestor A B | Exit 0 if A is an ancestor of B, else 1 |
| --fork-point <ref> [<branch>] | Find divergence using the reflog |
| --octopus | Find a common ancestor of more than two commits |
| --all | Print all merge bases when several exist |
In CI
This is the single biggest shallow-clone trap: with fetch-depth: 1 the common ancestor is below the clone boundary and merge-base returns nothing or the wrong commit, so PR diffs misfire. Use fetch-depth: 0 or deepen until the base is present. --is-ancestor is exit-code based; use it directly in if/&& rather than capturing stdout.
Common errors in CI
Empty output (and exit 1) from merge-base means no common ancestor was found locally, the classic shallow-clone symptom; --unshallow or deepen. "fatal: Not a valid commit name origin/main" means the remote-tracking ref was not fetched. --fork-point printing nothing means the reflog lacks the needed entries (fresh clone).