# branchguard

Clean up stale and merged git branches.

[![PyPI version](https://img.shields.io/pypi/v/branchguard)](https://pypi.org/project/branchguard/)
[![Downloads](https://img.shields.io/pypi/dm/branchguard)](https://pypi.org/project/branchguard/)
[![Python version](https://img.shields.io/pypi/pyversions/branchguard)](https://pypi.org/project/branchguard/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Install

```bash
pip install branchguard
```

```bash
uv tool install branchguard
```

```bash
brew install branchguard
```

## Usage

Scan for branches that can be pruned (dry run, nothing gets deleted):

```bash
branchguard
```

Or explicitly:

```bash
branchguard scan
```

Only show branches that have been merged into main:

```bash
branchguard scan --merged
```

Check against a different target branch:

```bash
branchguard scan --target develop
```

Show branches older than 30 days instead of the default 90:

```bash
branchguard scan --days 30
```

Include remote branches:

```bash
branchguard scan --remote
```

Actually delete the branches:

```bash
branchguard scan --force
```

Get JSON output:

```bash
branchguard scan --json
```

## What the output looks like

```
          branchguard
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
┃ Branch             ┃ Last Commit ┃ Age (days) ┃ Merged? ┃ Status  ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━┩
│ feature/old-login  │ 2024-08-15  │        185 │ yes     │ merged  │
│ fix/header-bug     │ 2024-09-01  │        168 │ no      │ stale   │
│ feature/signup     │ 2024-11-20  │         88 │ yes     │ merged  │
└────────────────────┴─────────────┴────────────┴─────────┴─────────┘

Found 3 branches to prune. Run with --force to delete.
```

## All options

| Option | Short | Default | Description |
|--------|-------|---------|-------------|
| `--days` | `-d` | `90` | Branches older than this many days are considered stale |
| `--merged` | `-m` | off | Only show branches merged into the target branch |
| `--target` | `-t` | `main` | Target branch to check merged status against |
| `--remote` | `-r` | off | Include remote branches |
| `--force` | `-f` | off | Actually delete branches (default is dry-run) |
| `--json` | `-j` | off | Output results as JSON |
| `--version` | `-V` | - | Show version and exit |

## Why I built this

I kept accumulating dozens of stale branches in every repo I worked on. Every few weeks I would manually run `git branch --merged` and delete them one by one, or I would forget and end up with 50+ branches cluttering my local. I wanted a single command that shows me what is safe to delete and lets me clean up in one shot.

## License

MIT
