{{ summaryHeading }}
{{ summaryPrimary }}
{{ summaryLine }}
{{ summaryStatus }} {{ stale_days }}-day rule {{ protectedCount }} protected
Branch cleanup policy and inventory
Paste a dated export, or load one local CSV, TSV, or TXT file. Source text is not added to the URL.
{{ sourceMeta }}
Drop one CSV, TSV, or TXT file onto the textarea; files over 2 MiB are refused.
{{ unknownDateCount }} branch row(s) have a missing or unreadable last-commit date. Repair those rows before deletion decisions.
This label is included in share URLs and exports. The branch inventory stays in this browser.
Use the short branch name, such as main or trunk.
Use the inventory export date so repeated audits remain comparable.
The threshold is a review policy, not deletion permission.
days
The shipped 10-day window warns owners before the 45-day stale rule.
days
Examples: main, release/*, hotfix/*.
Off keeps the active review focused on unmerged work.
{{ include_merged ? 'Merged rows included' : 'Merged rows hidden' }}
Zero applies no additional hold after a branch is marked merged.
days
{{ tableExportStatus.brief }}
MetricValueStatusNext actionCopy
{{ row.metric }}{{ row.value }}{{ row.status }}{{ row.next_action }}
{{ tableExportStatus.ledger }}
BranchLast commitAgeAuthorTrackingStateReview noteCopy
{{ row.branch }}{{ row.last_commit }}{{ row.age }}{{ row.author }}{{ row.tracking }}{{ row.state }}{{ row.review_note }}
{{ tableExportStatus.queue }}
BranchPressureEvidenceSuggested actionOwnerCopy
{{ row.branch }}{{ row.pressure }}{{ row.evidence }}{{ row.suggested_action }}{{ row.owner }}
No cleanup queue rows
The visible inventory has no stale, near-stale, diverged, merged, or unknown-date branches.
{{ chartExportStatus.age }}
No dated branches are visible. Check commit dates or include merged branches in Advanced.
Loading chart…
{{ chartExportStatus.divergence }}
No branches are visible for divergence. Include merged branches in Advanced or load an unmerged inventory.
Loading chart…

Old branch names make a repository harder to read, but age alone does not make a branch disposable. A quiet release branch may still be protected, while a recent feature branch can already be risky because its upstream vanished or it contains commits that never reached the default branch. Cleanup starts with evidence about the commit graph and team policy, not a list sorted by date.

Last-commit age
Whole calendar days from the recorded commit date to a fixed review date.
Ahead and behind
Commits unique to the branch and commits present on its upstream but missing locally.
Merged
The inventory says the branch work has been incorporated into its comparison target.
Gone upstream
The tracked remote branch is no longer advertised, although the local branch can still contain useful work.

A stale threshold is a review policy. Teams with short-lived feature work may choose a few weeks; repositories with maintained release lines may allow months. The near-stale window gives owners notice before the threshold, while protected names keep default, release, hotfix, or explicitly marked branches outside ordinary deletion work.

Merge status also needs a clear reference. Git's merged test is about reachability from a chosen commit, not a general promise that a branch is safe to remove everywhere. Pull requests, tags, release procedures, worktrees, forks, and deployment references can keep a branch useful after its tip is reachable from the default branch.

A good branch audit produces conversations and checks. It identifies work to keep, rebase, merge, close, delete after confirmation, or repair in the inventory. It should never turn a heuristic score into an automatic deletion command.

How to Use This Tool:

Take one dated snapshot and apply one repository policy so ages and comparisons remain reproducible.

  1. Enter the Repository, Default branch, and Reference date. The reference date should match the inventory snapshot rather than today's date.
  2. Choose the Stale threshold and Near-stale window. The near-stale window must be between 0 and the stale threshold.
  3. Set Protected branch terms for exact names, prefixes, or wildcard patterns. The default branch and any row marked protected are always protected.
  4. Paste or load a CSV, TSV, pipe-delimited, TXT, or recognizable git branch -vv inventory. A dated table is preferred because git branch -vv text alone does not contain the last-commit date.
  5. Choose whether to include merged branches and, if needed, set a Merged grace window. Repair duplicate names, negative divergence counts, or missing dates before acting on the queue.
  6. Start with Cleanup brief, then verify individual rows in Branch ledger and Cleanup queue against Git and the branch owner.

Interpreting Results:

Stale and Near stale describe age against the chosen policy, not deletion safety. Diverged is used only for a current-age branch that is ahead and at least 10 commits behind. Unknown date means the row needs repair before an age decision.

Cleanup pressure orders follow-up by age, divergence, state, open-review evidence, and a gone upstream. A higher number is a review priority, not permission to delete. Confirm reachability, unpushed commits, pull requests, worktrees, tags, release use, and owner intent with Git and the hosting service.

When merged branches are hidden, the visible counts and queue omit them, while protected and unknown-date counts still describe the complete parsed inventory where stated. Keep the same inclusion policy when comparing audit dates.

Technical Details:

Dates are interpreted as Gregorian calendar dates and reduced to whole-day serial values. Future commit dates do not produce negative age; their age is clamped to zero. Branch classification follows a fixed precedence, so protection and merge status override age, and a stale branch is not relabeled diverged.

Rule Core:

Git branch classification rules in evaluation order
Order Condition State
1Default branch, protected term match, or protected inventory flagProtected
2Inventory marks the branch mergedMerged; held when age is less than a positive merged grace window
3Last-commit date is missing or unreadableUnknown date
4Age is greater than or equal to the stale thresholdStale
5Age is greater than or equal to stale threshold minus near-stale windowNear stale
6Ahead is greater than 0 and behind is greater than or equal to 10Diverged
7No earlier rule matchesCurrent

Formula Core:

Age is the non-negative difference between the review date and commit date. Pressure combines bounded contributions so no single large count can dominate the 0 to 100 result.

age= max(0,reviewDay-commitDay) pressure= round(clamp(A+U+B+W+R+G,0,100))

A is age divided by the stale threshold, multiplied by 42 and capped at 58. U is ahead commits multiplied by 2.5 and capped at 24. B is behind commits multiplied by 0.8 and capped at 16. W is the state weight: 30 stale, 18 merged, 16 near stale, 14 diverged, 10 unknown date, or 0 current. R adds 6 for an open review and G adds 12 for a gone upstream. Protected branches always receive 0.

The inventory is limited to 2 MiB. Ahead and behind must be non-negative whole numbers, dates must begin with YYYY-MM-DD, and duplicate branch names are rejected case-insensitively.

Privacy and Limitations:

Inventory text is analyzed locally and is not placed in the page URL. It may still contain private repository names, branch names, authors, and pull-request identifiers, so review exported evidence before sharing it.

  • The analysis does not contact a Git remote or hosting service and cannot prove that upstream, merge, protection, or pull-request fields are current.
  • A protected-name match is a local policy rule, not confirmation of a server-side branch protection rule.
  • A gone upstream does not mean local commits are merged, backed up, or unwanted.