Skip to content

iamkorun/cuscus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🌿 cuscus

Audit your local git branches — spot stale, merged, and forgotten branches in a single table

CI Go Reference Go Report Card License: MIT Stars Buy Me a Coffee


The Problem

You open a repo you haven't touched in a month. Run git branch. Get this:

  chore/bump-deps
  feat/auth-refactor
  feat/dark-mode
  feat/old-experiment
* main
  release/v2.1
  wip/that-thing-from-last-quarter

Which of these are merged? Which are three months old and blocked on a review that never happened? git branch -v adds a commit hash and message — it doesn't answer the question you actually care about.

Branch sprawl is invisible until it isn't. You delete the wrong one, lose two days of work, or ship a stale branch to review because you forgot it diverged 47 commits ago.

The Solution

cuscus runs one command and prints a table that answers all of it at once:

$ cuscus

BRANCH                    AGE       AHEAD  BEHIND  STATUS
------------------------  --------  -----  ------  -------
* main                    just now  0      0       CURRENT
  feat/auth-refactor      3d ago    2      0       FRESH
  feat/dark-mode          6d ago    5      1       FRESH
  release/v2.1            18d ago   0      4       STALE
  feat/old-experiment     1mo ago   1      19      STALE
  chore/bump-deps         2mo ago   0      0       MERGED
  wip/that-thing          3mo ago   3      0       STALE

Named after the cuscus — a marsupial that clings tightly to tree branches. Fitting for a tool that clings to your git tree and refuses to let branches get away from you.

Demo

$ cd ~/code/big-monorepo
$ cuscus

BRANCH                       AGE        AHEAD  BEHIND  STATUS
---------------------------  ---------  -----  ------  -------
* main                       just now   0      0       CURRENT
  feat/auth-refactor         3d ago     2      0       FRESH
  feat/dark-mode             6d ago     5      1       FRESH
  release/v2.1               18d ago    0      4       STALE
  feat/old-experiment        1mo ago    1      19      STALE
  chore/bump-deps            2mo ago    0      0       MERGED
  wip/that-thing             3mo ago    3      0       STALE
$ cuscus --clean | sh    # only after you've reviewed
Deleted branch chore/bump-deps (was a1b2c3d).
Deleted branch release/v2.1 (was e4f5g6h).

Landing page with full demo →

Quick Start

go install github.com/iamkorun/cuscus/cmd/cuscus@latest
cd your-repo/
cuscus

Installation

Via go install (recommended)

go install github.com/iamkorun/cuscus/cmd/cuscus@latest

Requires Go 1.21+. The binary lands in $(go env GOPATH)/bin.

Pre-built binaries

Download a binary for your platform from the Releases page. No runtime required — single static binary.

Platform Architecture File
Linux x86_64 cuscus_linux_amd64.tar.gz
macOS Apple Silicon cuscus_darwin_arm64.tar.gz
macOS Intel cuscus_darwin_amd64.tar.gz
Windows x86_64 cuscus_windows_amd64.zip

Homebrew

# Coming soon
brew install iamkorun/tap/cuscus

Usage

Default — full branch table

cuscus
BRANCH                    AGE       AHEAD  BEHIND  STATUS
------------------------  --------  -----  ------  -------
* main                    just now  0      0       CURRENT
  feat/auth-refactor      3d ago    2      0       FRESH
  release/v2.1            18d ago   0      4       STALE
  chore/bump-deps         2mo ago   0      0       MERGED
  • CURRENT — the branch you are on right now
  • FRESH — active, within the stale threshold
  • STALE — no commits within the threshold (default: 14 days)
  • MERGED — fully merged into the base branch

Change the stale threshold

cuscus --days 30

Marks branches with no activity in the last 30 days as STALE instead of the default 14.

Specify a different base branch

cuscus --base develop

Ahead/behind counts and merged detection use develop instead of auto-detected main/master.

Print cleanup commands

cuscus --clean
git branch -d chore/bump-deps
git branch -D release/v2.1  # STALE — force delete
git branch -D feat/old-experiment  # STALE — force delete

⚠️ Warning: --clean uses -D (force delete) for STALE branches.

STALE branches are not fully merged into your base branch. Running the output of --clean through sh will permanently delete unmerged commits for any STALE branch listed.

Always review the output of cuscus --clean before piping it:

# Review first:
cuscus --clean

# Then pipe only if you are sure:
cuscus --clean | sh

cuscus itself never deletes anything. It only prints commands. You decide what runs.

Machine-readable output

cuscus --json | jq '.[] | select(.status == "STALE") | .branch.name'
"release/v2.1"
"feat/old-experiment"
"wip/that-thing"

Audit a different repo

cuscus -C /path/to/other-repo

Flags

Flag Short Default Description
--days N -d 14 Stale threshold in days
--base BRANCH -b auto Base branch for ahead/behind and merged detection
--clean false Print git branch -d/-D commands for merged/stale branches
--json false Machine-readable JSON output (no ANSI codes)
--dir PATH -C . Run against a specific repo directory
--verbose -v false Extra output (e.g. detected base branch)
--quiet -q false Suppress non-essential output
--version Print version and exit
--help -h Print help

Features

  • One-glance table — branch name, age, ahead/behind your base, and health status in a single view
  • Auto base detection — finds main, master, or your origin's HEAD without configuration
  • Safe cleanup--clean prints shell commands, never executes them; you pipe only when ready
  • JSON output — pipe to jq for scripting, CI gates, or custom dashboards
  • Color-aware — auto-disables ANSI when piped or when NO_COLOR is set
  • Zero config — run from any git repo, no setup required
  • Single static binary — no runtime, no dependencies, no Python/Node bootstrap

Exit codes

cuscus is designed to be scriptable.

Code Meaning
0 Success — even if there are stale or merged branches
1 Error — not in a git repo, invalid flags, or git failure

The presence of stale branches is not an error: it's the answer to a question you asked. If you want CI to fail when stale branches accumulate, parse the JSON:

# Fail if any branch is older than 30 days
if cuscus --days 30 --json | jq -e '. | any(.status == "STALE")' >/dev/null; then
  echo "::error::Stale branches detected"
  exit 1
fi

Comparison

Need git branch -v git for-each-ref cuscus
List branches yes yes yes
Last-commit age in human form no manual format yes
Ahead/behind vs base no no yes
Merged-into-base detection no no yes
Color-coded health status no no yes
Bulk-delete commands (review first) no no --clean
Machine-readable output for scripts no yes (raw) --json

Why "cuscus"?

The cuscus is a marsupial native to the forests of Papua New Guinea and northern Australia. It spends its entire life in the tree canopy, gripping branches with its prehensile tail and curved claws — never losing track of where it is in the tree.

That's the tool: something that clings to your git tree, accounts for every branch, and notices when one has been dead on the vine for too long.

Contributing

Contributions are welcome. Please open an issue first to discuss the change.

git clone https://github.com/iamkorun/cuscus.git
cd cuscus
go test ./...

License

MIT


Star History

Star History Chart

Buy Me a Coffee

About

Audit your local git branches — spot stale, merged, and convention-breaking branches in a single table.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages