Measure divergence with three numbers: how many upstream commits you lack, how many local commits upstream lacks, and how many lines your fork changes. Git gives all three with a symmetric commit count, a diff summary and a list of your own commits. Record them each time you sync.
Why a number beats a feeling
Teams say "we are pretty close to upstream" until a security fix lands and nobody can say whether it applies. A fork that is 12 commits behind is a quick sync. One that is 900 commits behind with 60 local patches is a project. Write the numbers down and you can see the trend, and you can decide when to act.
The three measurements
Assume a remote named upstream and a local branch named main that holds your fork.
git fetch upstream
git rev-list --left-right --count upstream/main...main
git diff --stat upstream/main main
git log --oneline upstream/main..main
The first command prints two counts separated by a tab. The Git documentation says that when the count option is combined with the left-right option, it prints the counts for left and right commits. With the three dot form above, the left number is commits only upstream has (how far behind you are) and the right number is commits only your branch has (what you carry).
The second command shows which files you changed and how much. The third lists your own commits, which is your patch list in plain form.
Read the numbers
| Behind | Ahead | Diff size | What it usually means |
|---|---|---|---|
| Small | Small | Small | Healthy, sync on the next release |
| Large | Small | Small | You are only a maintenance lag, sync soon |
| Small | Large | Large | You are building a product on top, plan ownership |
| Large | Large | Large | Real divergence, treat as a separate project |
The third column matters as much as the counts. Ten commits that touch one build file diverge less than two commits that rewrite a parser.
Catch cherry-picked fixes
If you backported an upstream security fix by cherry-pick, the plain count will show it as both behind and ahead, because the commit has a different ID in your branch. The Git documentation describes a cherry-pick option for these listings that omits commits introducing the same change as one on the other side. Use it so your carried list shows only real local changes:
git log --oneline --left-right --cherry-pick upstream/main...main
Track it over time
Add the numbers to a short file in the fork, or to your fork register, with the date and the upstream tag you compared against. The describe command, which finds the most recent tag reachable from a commit, is a handy way to label where upstream is: run it against the upstream branch and note the result.
Review the trend monthly. A rising behind count with a flat ahead count means you are drifting through neglect. A rising ahead count means you are changing the code on purpose, so check that each change has an owner and, where possible, an upstream plan. For that, see carrying a patch while waiting for an upstream merge and what security responsibilities come with maintaining a fork.
Where Safeguard fits
Divergence is a security question because every upstream advisory has to be checked against your copy. Safeguard's SBOM and dependency scanning can list the components in your builds, and you can try a free scan at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a component is listed with its version, because that is the field you compare against upstream.
Quick check
What does the left number from the symmetric count mean?
With the three dot form upstream/main...main, the left number is commits that only upstream has. It tells you how far behind you are.
Is a small commit count always low risk?
No. A few commits that rewrite core logic can diverge more than many small build changes. Read the diff size as well.
Sources
Last reviewed: 19 October 2026.