Git Basics: Count Commits Unique to Each Branch
Branch divergence is easier to reason about as two sets of reachable commits. Use a controlled fork to distinguish a two-dot exclusion range from a three-dot symmetric difference.
Prepare a scratch directory
Tested on Linux with Git 2.52.0 and GNU Bash 5.2.37. You need Bash, a text editor, the named runtime, and standard mktemp, rm, and rmdir utilities. The examples use only controlled local data; generated fixture directories are cleaned automatically.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Run the example
Save this as demonstrate-rev-list.sh:
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_AUTHOR_NAME='Example Author'
export GIT_AUTHOR_EMAIL='author@example.invalid'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
export GIT_AUTHOR_DATE='2026-10-28T00:00:00+00:00'
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git init -q -b main "$fixture_dir/repo"
cd -- "$fixture_dir/repo"
git config commit.gpgsign false
git config core.hooksPath /dev/null
git commit -qm 'Base' --allow-empty
git switch -qc feature
git commit -qm 'Feature one' --allow-empty
git commit -qm 'Feature two' --allow-empty
git switch -q main
git commit -qm 'Main one' --allow-empty
printf 'Only feature: '
git rev-list --count main..feature
printf 'Only main: '
git rev-list --count feature..main
printf 'Left and right unique counts:\n'
git rev-list --left-right --count main...feature
test "$(git rev-list --count main..feature)" -eq 2
test "$(git rev-list --count feature..main)" -eq 1Run it:
bash demonstrate-rev-list.shObserved output:
Only feature: 2
Only main: 1
Left and right unique counts:
1 2Read the result
main..feature includes commits reachable from feature but not main. Reversing the endpoints reverses the exclusion. With three dots, --left-right counts unique commits on the left and right separately; the tab-separated result is one and two.
Apply it carefully
Counts measure commit identity and reachability, not lines changed or patch equivalence. Cherry-picked commits can have different identities despite equivalent changes. Empty commits are intentional here so that the graph, rather than file contents, is the subject of the example. Run this script from an ordinary shell with no repository-selection variables such as GIT_DIR or GIT_WORK_TREE set. All commits and cleanup stay inside the newly created temporary fixture.
The official reference describes the behavior and options. These checks cover the fixture above rather than every input or platform.
Clean up
Remove the saved source, return to the starting directory, then remove the empty practice directory:
rm -- demonstrate-rev-list.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect its remaining contents rather than deleting unknown files.
Acknowledgements
This post was created with assistance from AI.