Using Git, show all commits that are in one branch, but not the others
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When branches diverge, you often need to answer a very specific question: which commits exist on one branch and are absent from another. Git has several commands for this, and choosing the right one depends on whether you want a simple list, a two-way comparison, or a check based on patch content rather than raw commit IDs.
The Basic Branch Range Syntax
The most direct answer uses git log with the two-dot range.
This means "show commits reachable from feature that are not reachable from main." In practice, it lists the commits that are unique to feature.
To see the opposite direction, swap the names:
That command shows commits that are on main but not on feature.
If you only want a compact one-line output, add --oneline.
Comparing Both Sides at Once
Sometimes you want to see unique commits from both branches in one command. Use the three-dot form with --left-right.
Lines prefixed with < belong only to the left side, which is main here. Lines prefixed with > belong only to feature.
That view is useful before merges or rebases because it shows the full divergence rather than only one branch's extra commits.
Checking One Branch Against Several Others
The question sometimes means "show commits on my branch that are not on any of these other branches." In that case, --not is clearer than trying to stack several range expressions.
This means "start from feature, then exclude anything reachable from main, release, or hotfix." It is a good fit when you want to know whether a feature branch still contains work that has not landed anywhere else.
Looking for Equivalent Changes Instead of Raw Commits
Git history can be rewritten. A commit may exist under a different hash after a rebase or cherry-pick even though the code change is effectively the same. For that case, git cherry is often better than git log.
Lines marked with + are changes present in feature that Git does not consider equivalent to anything on main. Lines marked with - represent changes that already exist there in equivalent patch form.
This is especially helpful when reviewing branch status after cherry-picks.
A Practical Example
Suppose you want to see what your local branch has that the remote main branch does not.
Using HEAD keeps the command portable no matter what your current branch is. Fetching first matters because stale remote-tracking refs lead to stale answers.
Common Pitfalls
The most common mistake is reversing the range. main..feature and feature..main answer different questions, so double-check the left and right side before trusting the output.
Another pitfall is forgetting to fetch remote updates. Comparing against origin/main without a recent git fetch may show commits as unique even though the remote branch has already moved.
Developers also confuse two-dot and three-dot syntax. With git log, two-dot means "reachable from the right side but not the left side." Three-dot means "commits reachable from either side, but not both," which is a symmetric difference. It is useful, but it answers a broader question.
Finally, remember that commit identity and patch identity are not the same thing. If a branch was rebased, git log may show commits as different while git cherry shows that the actual code changes have already been applied elsewhere.
Summary
- Use
git log main..featureto show commits unique tofeature. - Use
git log --left-right main...featureto inspect divergence from both sides. - Use
git log feature --not main releasewhen comparing one branch against several others. - Use
git cherrywhen rebases or cherry-picks make commit hashes unreliable. - Fetch remotes first and pay close attention to range direction so you answer the intended question.

