Git
Branching
Version Control
Development
Git Commands

Finding a branch point with Git?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A branch point (or fork point) is the commit where a branch diverged from its parent branch. Git does not explicitly store this information — branches are just pointers to commits, and any commit can be an ancestor of multiple branches. To find the branch point, you use git merge-base to find the common ancestor between two branches. This is essential for understanding what changed on a branch, preparing for merges, or creating targeted rebases.

Method 1: git merge-base (Most Common)

bash
1# Find the common ancestor of feature-branch and main
2git merge-base feature-branch main
3# Output: a1b2c3d4e5f6... (the commit hash where they diverged)
4
5# See the commit details
6git log -1 $(git merge-base feature-branch main)

git merge-base finds the best common ancestor — the most recent commit that is reachable from both branches. This is the branch point.

 
1main:     A --- B --- C --- D --- E
2                 \
3feature:          F --- G --- H
4
5git merge-base feature main → B

Method 2: git merge-base --fork-point (Reflog-Aware)

bash
# Fork-point uses the reflog to find where feature diverged from main
git merge-base --fork-point main feature-branch

--fork-point consults the reflog to handle cases where main was rebased or force-pushed after the branch was created. It finds the original fork point even if the common ancestor changed.

bash
1# Scenario: main was rebased after feature branched off
2# Without --fork-point: may return a wrong ancestor
3# With --fork-point: uses reflog to find the true fork point
4
5# Note: --fork-point requires the reflog to contain the relevant entries
6# Reflogs expire after 90 days by default

Method 3: Visual with git log --graph

bash
1# See the branch structure visually
2git log --graph --oneline --all --decorate
3
4# Output:
5# * d4e5f6a (HEAD -> main) Latest on main
6# * c3d4e5f Add feature X
7# | * h7i8j9k (feature-branch) Feature work 3
8# | * g6h7i8j Feature work 2
9# | * f5g6h7i Feature work 1
10# |/
11# * b2c3d4e <-- This is the branch point
12# * a1b2c3d Initial commit

Method 4: git log with Range

bash
1# Show commits on feature-branch that are NOT on main
2git log main..feature-branch --oneline
3
4# Show the first commit of the feature branch (closest to branch point)
5git log main..feature-branch --oneline --reverse | head -1
6
7# Show the branch point commit itself
8git log -1 $(git merge-base feature-branch main) --oneline
bash
# Show commits on main that are NOT on feature-branch (happened after fork)
git log feature-branch..main --oneline

Method 5: git diff from Branch Point

bash
1# See all changes made on feature-branch since it diverged from main
2git diff $(git merge-base feature-branch main)..feature-branch
3
4# Shorthand using three-dot syntax
5git diff main...feature-branch
6# This shows changes on feature-branch relative to the merge base

The three-dot ... syntax in git diff automatically uses the merge base, showing only what changed on the right side since divergence.

Method 6: Find Branch Point in a Script

bash
1#!/bin/bash
2# find-branch-point.sh — Find where the current branch diverged from a base
3
4BASE=${1:-main}
5CURRENT=$(git rev-parse --abbrev-ref HEAD)
6
7BRANCH_POINT=$(git merge-base "$BASE" "$CURRENT")
8
9echo "Branch: $CURRENT"
10echo "Base:   $BASE"
11echo "Branch point: $BRANCH_POINT"
12echo ""
13echo "Commits since branch point:"
14git log --oneline "$BRANCH_POINT".."$CURRENT"
15echo ""
16echo "Files changed since branch point:"
17git diff --stat "$BRANCH_POINT".."$CURRENT"
bash
1chmod +x find-branch-point.sh
2./find-branch-point.sh main
3# Branch: feature-auth
4# Base:   main
5# Branch point: b2c3d4e
6# Commits since branch point:
7# h7i8j9k Add login validation
8# g6h7i8j Create auth service
9# f5g6h7i Add user model

Multiple Merge Bases

When branches have been merged back and forth, there can be multiple common ancestors:

bash
1# Show all common ancestors (not just the best one)
2git merge-base --all feature-branch main
3
4# Octopus merge base (3+ branches)
5git merge-base --octopus branch-a branch-b branch-c
 
1main:     A --- B --- C --- M --- D
2                 \       /
3feature:          F --- G --- H
4
5# After merging main into feature (or vice versa),
6# git merge-base may return G or C depending on the merge direction

Practical Use Cases

Rebase onto the correct point

bash
# Rebase feature-branch onto latest main, starting from the branch point
git rebase --onto main $(git merge-base main feature-branch) feature-branch

Create a patch of all branch changes

bash
# Generate a patch file of everything since the branch point
git format-patch $(git merge-base main feature-branch)..feature-branch

Count commits on a branch

bash
# How many commits on feature-branch since it diverged from main?
git rev-list --count $(git merge-base main feature-branch)..feature-branch
# Output: 3

Common Pitfalls

  • Assuming Git stores the branch point explicitly: Git does not record where a branch was created. It only stores commit parents. git merge-base computes the branch point from the commit graph each time. If the graph is complex (many merges), the result may not match your intuition.
  • Reflog expiration with --fork-point: --fork-point depends on the reflog, which expires after 90 days by default. On CI servers or fresh clones, the reflog may be empty, causing --fork-point to return nothing. Use plain git merge-base as a fallback.
  • Shallow clones: git clone --depth N creates a shallow clone with limited history. git merge-base may fail or return incorrect results because the branch point commit is not in the local repository. Use git fetch --unshallow to get full history.
  • Confusing .. and ... in git log vs git diff: In git log, A..B shows commits in B not in A. In git diff, A...B uses the merge base (branch point). The three-dot syntax has different meanings depending on the command.
  • Multiple merge bases after criss-cross merges: If branches have been merged back and forth, git merge-base returns the most recent common ancestor, which might not be the original fork point. Use git merge-base --all to see all candidates.

Summary

  • Use git merge-base feature main to find the commit where a branch diverged
  • Use --fork-point for reflog-aware detection (handles rebased base branches)
  • Use git diff main...feature (three dots) to see changes since the branch point
  • Use git log main..feature (two dots) to list commits on the feature branch
  • Git does not store branch points explicitly — they are computed from the commit graph
  • Shallow clones and expired reflogs can cause incorrect branch point detection

Course illustration
Course illustration

All Rights Reserved.