Align Branches
Finds fixes that live on your staging branch but never reached master — the bugs
that are resolved in staging and silently still broken in production.
The problem
You branch from master, cherry-pick into a staging branch, then fix the bugs
staging surfaces on the staging branch. Some of those fixes never get copied
back. Staging is green, production still has the bug, and nothing tells you.
git cherry origin/master origin/staging is the one-liner that finds these, but
it compares patch IDs, so on a real repository most of its output is noise from
rebases, adapted ports and other people's work. This extension is that command
plus the checks that make the output small enough to act on.
Features, and how to use each one
Everything lives in one place: the Branch alignment panel at the bottom of
the Source Control sidebar (Ctrl+Shift+G). Commands are in the Command
Palette (Ctrl+Shift+P) under Align Branches. Settings are in
Ctrl+, under Align Branches.
Set up
| I want to |
Do this |
| Tell it which branches to compare |
Create .alignbranches.json in the repo root (see Configuration below), or run Align Branches: Install pre-push hook and let it write a starter for you |
| Block pushes that would strand a fix |
Align Branches: Install pre-push hook in this repo |
| Undo that |
Align Branches: Remove pre-push hook from this repo |
| Find out why something is not working |
Align Branches: Check setup, or the Check setup button (pulse icon) on the panel toolbar |
| Start clean on an old repo |
Align Branches: Accept all current drift — see First run below |
See what is unported
| I want to |
Do this |
| See the list |
Open the Branch alignment panel in the Source Control sidebar |
| See a count at a glance |
The status bar shows N unported, amber when something is missing. Click it to open the panel. Hide it with alignBranches.showStatusBar |
| Re-check now |
The Refresh button on the panel toolbar. It also re-checks on an interval and when your branches change (alignBranches.autoRefresh) |
| Compare against the latest remote state |
Turn on alignBranches.fetchOnRefresh, or run git fetch yourself. Off by default so it never blocks on the network |
| See only my commits, or everyone's |
The Toggle scope button (person icon) on the panel toolbar. Defaults to yours — set alignBranches.authors to [] for everyone |
Understand one commit
| I want to |
Do this |
| See the two branches side by side |
Click the commit. Upstream left, downstream right, for the files it touched. Contents come straight from git, so it works with a dirty worktree |
| See the commit's own patch |
Right-click → Show commit patch |
| See every file that differs between the branches |
The Compare all files button on the panel toolbar. Each file is labelled only on staging / only on master / differs |
| Know why it was flagged |
Hover the commit. The reason is in the tooltip and under each entry |
| Copy the SHA |
Right-click → Copy commit SHA |
Act on it
Hover a commit and three buttons appear:
| Button |
What it does |
| Compare |
Side-by-side branch diff, same as clicking |
| Port |
Cherry-picks the commit to the target with -x. Asks whether to put it on a new branch (arrives by pull request) or straight onto the target branch. Set alignBranches.portMode to stop being asked |
| Accept |
Marks it downstream-only so it stops being reported. Offers Undo. Writes to .alignbranches.json, so it applies to everyone once committed |
To un-accept something later: Align Branches: Stop accepting a commit as
downstream-only, or delete the SHA from ignoreCommits by hand.
The pre-push hook
The panel only helps when you look at it. The hook stops you at the moment you
push — the last point before a gap becomes a production gap.
Install it with Align Branches: Install pre-push hook in this repo. That is
the whole setup; the extension ships the hook and installs it for you.
- Pushing an ordinary branch prints what is unported and pushes anyway.
- Pushing a branch matching
blockOnPush refuses if something of yours is
missing. Globs work, so "*_master" matches TICKET-123_thing_master.
- If a branch in your config cannot be found, it blocks and says so rather than
reporting a clean result for something it never checked.
ALIGN_BRANCHES_SKIP=1 git push overrides.
ALIGN_BRANCHES_ALL_AUTHORS=1 git push widens it to the whole team.
Hooks are per repository and per clone — git will not run a hook that arrives
with a clone, so run the command once in each repo. Node.js must be on your
PATH, or ALIGN_BRANCHES_NODE pointed at a node binary.
Settings
| Setting |
Default |
What it does |
alignBranches.authors |
["me"] |
Whose commits to show. me resolves to your git user.email. [] shows everyone |
alignBranches.portMode |
ask |
branch always cuts a new branch, direct always cherry-picks onto the target |
alignBranches.autoRefresh |
true |
Re-check on an interval and when branches change |
alignBranches.refreshIntervalSeconds |
300 |
How often |
alignBranches.fetchOnRefresh |
false |
Fetch before checking. Accurate but hits the network |
alignBranches.showStatusBar |
true |
Show the counter |
Configuration
Create .alignbranches.json in your repository root:
{
"pairs": [{ "from": "origin/staging", "to": "origin/master" }],
"authors": ["me"],
"ignoreMarkers": ["[no-backport]", "[staging-only]"],
"lookbackDays": 90
}
With no config file it defaults to origin/staging → origin/master and works
immediately if your branches are named that.
Settings: alignBranches.authors, alignBranches.autoRefresh,
alignBranches.refreshIntervalSeconds, alignBranches.fetchOnRefresh,
alignBranches.showStatusBar.
First run
An established repository will show years of accumulated drift. Run
Align Branches: Accept all current drift from the Command Palette to set
a baseline, commit .alignbranches.json, and only new drift is reported after that.
A note on what this is for
The extension is a safety net, not the fix. The fix is direction: write bug
fixes on a branch off master and cherry-pick forward into staging, so staging
is strictly downstream and nothing can be stranded there. If this panel is
regularly full, that's the process telling you something.
The same detection core also runs as a CLI, a pre-push hook and a CI gate — an
editor panel only helps when you happen to look at it, while a blocked merge
stops a release. See the project repository.
Requirements
Git, and a full clone. Patch comparison needs real history; on a shallow clone
every commit looks unported (the extension warns when it detects this).
License
MIT