Name | git-branches JSON |
Version |
0.1.1
JSON |
| download |
home_page | None |
Summary | Interactive Git branch browser with fzf integration and GitHub PR status |
upload_time | 2025-08-13 21:51:46 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.12 |
license | None |
keywords |
git
fzf
github
cli
branch-management
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# git-branches
[](#requirements)
[](https://docs.astral.sh/ruff/)
[](https://github.com/chmouel/git-branches/actions/workflows/homebrew.yml)
[](https://github.com/chmouel/git-branches/actions/workflows/precommit.yml)
[](../../LICENSE)
An interactive Git branch browser powered by fzf, with rich previews for GitHub PRs and CI status. It’s fast, keyboard-first, and designed for day-to-day workflows: jump to branches, spin up local tracking from remotes, open the PR in your browser, or prune branches in bulk.
<img width="3724" height="2474" alt="Screenshot-1755094549-ghostty" src="https://github.com/user-attachments/assets/76b34908-d6b3-4be5-a720-222ee6894e7b" />
🍺 Homebrew CI: [](https://github.com/chmouel/git-branches/actions/workflows/homebrew.yml)
## TL;DR ⚡️
```bash
# Install (Homebrew tap)
brew tap chmouel/git-branches https://github.com/chmouel/git-branches
brew install --HEAD chmouel/git-branches/git-branches
# Browse local branches (preview on top)
git-branches
# Browse remote branches (pick a remote)
git-branches -r
# Show pushed-status icons for local branches
git-branches -s # add -S to show all
# Show GitHub Actions status (fetch over network)
git-branches --checks
```
## Highlights
- fzf-native UX: reverse list, previews, key bindings, multi-select for deletes.
- Rich preview: PR status (Open/Draft/Merged/Closed), OSC-8 link to the PR, CI combined status, and the last 10 commits with colors.
- GitHub awareness: shows whether a local branch exists on the remote (`-s`) and the CI status for the PR head commit.
- One-keystroke actions: checkout, open PR (`ctrl-o`), delete quickly (`alt-k`).
## Requirements
- git and fzf on PATH
- Python 3.12+ (uv-managed)
- Optional: `GITHUB_TOKEN` (improves rate limits and enables private repos)
- Optional: a Nerd Font for icons (fallback text is still readable)
## Installation 🍺
- Local dev via uv
- `make install`
- `make run` (or pass flags with `ARGS="..."`)
- System-wide (optional)
- From this directory: `uv tool install .`
- Then invoke the console script: `git-branches`
### Homebrew (Tap)
You can install via a Homebrew tap that ships a Formula for `git-branches`.
Option A — tap this repo directly (HEAD installs from the main branch):
```bash
brew tap chmouel/git-branches https://github.com/chmouel/git-branches
brew install --HEAD chmouel/git-branches/git-branches
```
Option B — local developer tap (no remote push needed):
```bash
TAP="${USER}/git-branches-dev"
brew tap-new "$TAP"
TAP_DIR="$(brew --repo "$TAP")"
mkdir -p "$TAP_DIR/Formula"
cp Formula/git-branches.rb "$TAP_DIR/Formula/"
brew install --HEAD "$TAP/git-branches"
```
Or use the Makefile helper (does the same steps for you):
```bash
make brew-local
# or pick a custom tap name
make brew-local TAP="${USER}/git-branches-dev"
```
Option C — copy `Formula/git-branches.rb` into your own GitHub tap repo (recommended for teams) and install:
```bash
brew tap <org>/<tap>
brew install --HEAD <org>/<tap>/git-branches
```
Notes:
- The Formula uses Homebrew’s Python virtualenv and installs `git-branches` along with its Python dependencies.
- Runtime dependencies `git` and `fzf` are declared and installed by Homebrew.
- `--HEAD` installs from the main branch. For a pinned/stable release, update the Formula `url` and `sha256` to a tagged tarball.
## Quickstart 🚀
- Browse and checkout local branches:
- `git-branches`
- Browse remotes and checkout (creates tracking branch if needed):
- `git-branches -r` (select remote interactively)
- `git-branches -R origin`
- Deletion workflows:
- `git-branches -d` (delete local; multi-select)
- `git-branches -D -R origin` (delete remote)
- See if local branches exist on the remote:
- `git-branches -s` (shows pushed status with default limit of 10)
- `git-branches -s -S` (disable default limit)
## Command-line options 🧭
- `-r`: Browse remote branches (choose remote via fzf)
- `-R <remote>`: Browse a specific remote (e.g., origin)
- `-d`: Delete local branches (multi-select)
- `-D`: Delete remote branches (multi-select)
- `-s`: Show pushed status for local branches (GitHub API)
- `-n <N>`: Limit to first N branches
- `-S`: With `-s`, disable default limit (show all)
- `-C`: Disable colors
- `-l`: List-only mode (no checkout)
- `--refresh`: Force refresh of PR cache (ignore stale cache and ETag)
- `--checks`: Fetch and show GitHub Actions status (preview and a small indicator in rows). Without this flag, cached results (if available) are still displayed, but no network calls are made for checks.
## Icons legend 🔤
- PR state:
- Open: `` (green)
- Draft: `` (yellow)
- Merged: `` (magenta)
- Closed: `` (red)
- GitHub Actions:
- In progress: `` (yellow)
- Success: `` (green)
- Failed/Timed out: `` (red)
- Cancelled: `` (red)
- Skipped/Neutral: `` (cyan)
Tip: Use a Nerd Font for best results. Without it, the text remains legible.
## Key bindings (fzf)
- `ctrl-o`: Open the PR for the highlighted ref in the default browser
- `alt-k`: Force-delete highlighted local branch (quick action)
## Shell Completion 🔌
Supported shells and scripts under `contrib/`:
- Zsh: `_git-branches`
- Bash: `git-branches.bash`
- Fish: `git-branches.fish`
### Zsh
Add the `contrib` directory to your `fpath` in `.zshrc` and re-init completions:
```zsh
fpath+=($PWD/contrib)
autoload -U compinit && compinit
```
Use the absolute path to your clone instead of `$PWD` in your dotfiles.
### Bash
Source the completion script from your `.bashrc` or `.bash_profile`:
```bash
source /absolute/path/to/contrib/git-branches.bash
```
### Fish
Copy or symlink the Fish completion to your user completions directory:
```fish
mkdir -p ~/.config/fish/completions
ln -sf /absolute/path/to/contrib/git-branches.fish ~/.config/fish/completions/git-branches.fish
```
### Arch Linux (PKGBUILD / AUR-style)
This repository includes a `PKGBUILD` under `aur/` for a `-git` style package (builds from HEAD).
- Build locally with makepkg (requires `base-devel`):
```bash
cd aur
makepkg -sci --noconfirm
```
## How it works
- Uses git for data (branch lists, recent commits) and fzf for the UI.
- Detects GitHub repository from the upstream of the current branch when possible, falling back to `origin` or the first remote.
- For `-s` and preview CI status, calls the GitHub API with `Authorization: Bearer $GITHUB_TOKEN` when set.
## Performance and Caching ⚙️
To improve performance and reduce API calls, `git-branches` batches git metadata and PR queries and caches PR data locally.
- Git metadata: branches and last-commit info are fetched via a single `git for-each-ref` call.
- PR list: fetched via REST in one call (`/pulls?state=open&per_page=100`) with ETag support; a small slice of recently closed PRs is also fetched to catch merges.
- Disk cache: `~/.cache/git-branches/prs.json` with `timestamp`, `etag`, and a `{head.ref -> PR}` map. Default TTL: 5 minutes.
Controls:
- `GIT_BRANCHES_OFFLINE=1`: skip all GitHub API calls.
- `GIT_BRANCHES_PREFETCH_DETAILS=1`: batch GraphQL for labels/reviews/body to make previews instant.
- `GIT_BRANCHES_NO_CACHE=1`: ignore and do not write disk cache; do not use in-memory caches.
- `--refresh` or `GIT_BRANCHES_REFRESH=1`: ignore existing cache and ETag this run, then write a fresh cache.
## Environment Variables 🔧
- `GIT_BRANCHES_OFFLINE=1`: Run fully offline (no GitHub requests).
- `GIT_BRANCHES_NO_CACHE=1`: Bypass disk/memory caching and ETag.
- `GIT_BRANCHES_REFRESH=1`: Force refresh of caches for this run.
- `GIT_BRANCHES_PREFETCH_DETAILS=1`: Prefetch PR details (GraphQL batches).
- `GIT_BRANCHES_SHOW_CHECKS=1`: Allow fetching Actions status (same as `--checks`). If unset, cached checks are still displayed; no fetches.
- `GIT_BRANCHES_NO_PROGRESS=1`: Disable spinners/progress indicators.
## Troubleshooting 🛠️
- “fzf not found”: Install fzf and ensure it’s on PATH (`brew install fzf`, `apt install fzf`, etc.).
- “Not in a git repository”: Run within a git repo.
- No icons? Install a Nerd Font and configure your terminal to use it.
- Low API rate limit? Set `GITHUB_TOKEN` (a classic or fine-grained PAT works).
- Homebrew says “formula not in a tap”: create a local tap and install:
```bash
TAP="${USER}/git-branches-dev"
brew tap-new "$TAP"
TAP_DIR="$(brew --repo "$TAP")"
mkdir -p "$TAP_DIR/Formula"
cp Formula/git-branches.rb "$TAP_DIR/Formula/"
brew install --HEAD "$TAP/git-branches"
```
## Development 🧪
- Lint: `make lint` (auto-fix: `make fix`)
- Tests: `make test` (pytest)
- Dev loop: `make dev` (ruff fix → pytest → ruff format)
- Format: `make format` (ruff)
## License
See the repository’s `LICENSE` file.
Raw data
{
"_id": null,
"home_page": null,
"name": "git-branches",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "git, fzf, github, cli, branch-management",
"author": null,
"author_email": "Your Name <your.email@example.com>",
"download_url": "https://files.pythonhosted.org/packages/f2/fb/a18ec8e7f582ce6284e9d1eed3956cc874bb42db361674a1c448e4be0959/git_branches-0.1.1.tar.gz",
"platform": null,
"description": "# git-branches\n\n[](#requirements)\n[](https://docs.astral.sh/ruff/)\n[](https://github.com/chmouel/git-branches/actions/workflows/homebrew.yml)\n[](https://github.com/chmouel/git-branches/actions/workflows/precommit.yml)\n[](../../LICENSE)\n\nAn interactive Git branch browser powered by fzf, with rich previews for GitHub PRs and CI status. It\u2019s fast, keyboard-first, and designed for day-to-day workflows: jump to branches, spin up local tracking from remotes, open the PR in your browser, or prune branches in bulk.\n\n<img width=\"3724\" height=\"2474\" alt=\"Screenshot-1755094549-ghostty\" src=\"https://github.com/user-attachments/assets/76b34908-d6b3-4be5-a720-222ee6894e7b\" />\n\n\ud83c\udf7a Homebrew CI: [](https://github.com/chmouel/git-branches/actions/workflows/homebrew.yml)\n\n## TL;DR \u26a1\ufe0f\n\n```bash\n# Install (Homebrew tap)\nbrew tap chmouel/git-branches https://github.com/chmouel/git-branches\nbrew install --HEAD chmouel/git-branches/git-branches\n\n# Browse local branches (preview on top)\ngit-branches\n\n# Browse remote branches (pick a remote)\ngit-branches -r\n\n# Show pushed-status icons for local branches\ngit-branches -s # add -S to show all\n\n# Show GitHub Actions status (fetch over network)\ngit-branches --checks\n```\n\n## Highlights\n\n- fzf-native UX: reverse list, previews, key bindings, multi-select for deletes.\n- Rich preview: PR status (Open/Draft/Merged/Closed), OSC-8 link to the PR, CI combined status, and the last 10 commits with colors.\n- GitHub awareness: shows whether a local branch exists on the remote (`-s`) and the CI status for the PR head commit.\n- One-keystroke actions: checkout, open PR (`ctrl-o`), delete quickly (`alt-k`).\n\n## Requirements\n\n- git and fzf on PATH\n- Python 3.12+ (uv-managed)\n- Optional: `GITHUB_TOKEN` (improves rate limits and enables private repos)\n- Optional: a Nerd Font for icons (fallback text is still readable)\n\n## Installation \ud83c\udf7a\n\n- Local dev via uv\n - `make install`\n - `make run` (or pass flags with `ARGS=\"...\"`)\n\n- System-wide (optional)\n - From this directory: `uv tool install .`\n - Then invoke the console script: `git-branches`\n\n### Homebrew (Tap)\n\nYou can install via a Homebrew tap that ships a Formula for `git-branches`.\n\nOption A \u2014 tap this repo directly (HEAD installs from the main branch):\n\n```bash\nbrew tap chmouel/git-branches https://github.com/chmouel/git-branches\nbrew install --HEAD chmouel/git-branches/git-branches\n```\n\nOption B \u2014 local developer tap (no remote push needed):\n\n```bash\nTAP=\"${USER}/git-branches-dev\"\nbrew tap-new \"$TAP\"\nTAP_DIR=\"$(brew --repo \"$TAP\")\"\nmkdir -p \"$TAP_DIR/Formula\"\ncp Formula/git-branches.rb \"$TAP_DIR/Formula/\"\nbrew install --HEAD \"$TAP/git-branches\"\n```\n\nOr use the Makefile helper (does the same steps for you):\n\n```bash\nmake brew-local\n# or pick a custom tap name\nmake brew-local TAP=\"${USER}/git-branches-dev\"\n```\n\nOption C \u2014 copy `Formula/git-branches.rb` into your own GitHub tap repo (recommended for teams) and install:\n\n```bash\nbrew tap <org>/<tap>\nbrew install --HEAD <org>/<tap>/git-branches\n```\n\nNotes:\n\n- The Formula uses Homebrew\u2019s Python virtualenv and installs `git-branches` along with its Python dependencies.\n- Runtime dependencies `git` and `fzf` are declared and installed by Homebrew.\n- `--HEAD` installs from the main branch. For a pinned/stable release, update the Formula `url` and `sha256` to a tagged tarball.\n\n## Quickstart \ud83d\ude80\n\n- Browse and checkout local branches:\n - `git-branches`\n- Browse remotes and checkout (creates tracking branch if needed):\n - `git-branches -r` (select remote interactively)\n - `git-branches -R origin`\n- Deletion workflows:\n - `git-branches -d` (delete local; multi-select)\n - `git-branches -D -R origin` (delete remote)\n- See if local branches exist on the remote:\n - `git-branches -s` (shows pushed status with default limit of 10)\n - `git-branches -s -S` (disable default limit)\n\n## Command-line options \ud83e\udded\n\n- `-r`: Browse remote branches (choose remote via fzf)\n- `-R <remote>`: Browse a specific remote (e.g., origin)\n- `-d`: Delete local branches (multi-select)\n- `-D`: Delete remote branches (multi-select)\n- `-s`: Show pushed status for local branches (GitHub API)\n- `-n <N>`: Limit to first N branches\n- `-S`: With `-s`, disable default limit (show all)\n- `-C`: Disable colors\n- `-l`: List-only mode (no checkout)\n- `--refresh`: Force refresh of PR cache (ignore stale cache and ETag)\n- `--checks`: Fetch and show GitHub Actions status (preview and a small indicator in rows). Without this flag, cached results (if available) are still displayed, but no network calls are made for checks.\n\n## Icons legend \ud83d\udd24\n\n- PR state:\n - Open: `\uf407` (green)\n - Draft: `\uf41f` (yellow)\n - Merged: `\uf419` (magenta)\n - Closed: `\uf05e` (red)\n- GitHub Actions:\n - In progress: `\uf251` (yellow)\n - Success: `\uf058` (green)\n - Failed/Timed out: `\uf057` (red)\n - Cancelled: `\uf05e` (red)\n - Skipped/Neutral: `\uf192` (cyan)\n\nTip: Use a Nerd Font for best results. Without it, the text remains legible.\n\n## Key bindings (fzf)\n\n- `ctrl-o`: Open the PR for the highlighted ref in the default browser\n- `alt-k`: Force-delete highlighted local branch (quick action)\n\n## Shell Completion \ud83d\udd0c\n\nSupported shells and scripts under `contrib/`:\n\n- Zsh: `_git-branches`\n- Bash: `git-branches.bash`\n- Fish: `git-branches.fish`\n\n### Zsh\n\nAdd the `contrib` directory to your `fpath` in `.zshrc` and re-init completions:\n\n```zsh\nfpath+=($PWD/contrib)\nautoload -U compinit && compinit\n```\n\nUse the absolute path to your clone instead of `$PWD` in your dotfiles.\n\n### Bash\n\nSource the completion script from your `.bashrc` or `.bash_profile`:\n\n```bash\nsource /absolute/path/to/contrib/git-branches.bash\n```\n\n### Fish\n\nCopy or symlink the Fish completion to your user completions directory:\n\n```fish\nmkdir -p ~/.config/fish/completions\nln -sf /absolute/path/to/contrib/git-branches.fish ~/.config/fish/completions/git-branches.fish\n```\n\n### Arch Linux (PKGBUILD / AUR-style)\n\nThis repository includes a `PKGBUILD` under `aur/` for a `-git` style package (builds from HEAD).\n\n- Build locally with makepkg (requires `base-devel`):\n\n```bash\ncd aur\nmakepkg -sci --noconfirm\n```\n\n## How it works\n\n- Uses git for data (branch lists, recent commits) and fzf for the UI.\n- Detects GitHub repository from the upstream of the current branch when possible, falling back to `origin` or the first remote.\n- For `-s` and preview CI status, calls the GitHub API with `Authorization: Bearer $GITHUB_TOKEN` when set.\n\n## Performance and Caching \u2699\ufe0f\n\nTo improve performance and reduce API calls, `git-branches` batches git metadata and PR queries and caches PR data locally.\n\n- Git metadata: branches and last-commit info are fetched via a single `git for-each-ref` call.\n- PR list: fetched via REST in one call (`/pulls?state=open&per_page=100`) with ETag support; a small slice of recently closed PRs is also fetched to catch merges.\n- Disk cache: `~/.cache/git-branches/prs.json` with `timestamp`, `etag`, and a `{head.ref -> PR}` map. Default TTL: 5 minutes.\n\nControls:\n\n- `GIT_BRANCHES_OFFLINE=1`: skip all GitHub API calls.\n- `GIT_BRANCHES_PREFETCH_DETAILS=1`: batch GraphQL for labels/reviews/body to make previews instant.\n- `GIT_BRANCHES_NO_CACHE=1`: ignore and do not write disk cache; do not use in-memory caches.\n- `--refresh` or `GIT_BRANCHES_REFRESH=1`: ignore existing cache and ETag this run, then write a fresh cache.\n\n## Environment Variables \ud83d\udd27\n\n- `GIT_BRANCHES_OFFLINE=1`: Run fully offline (no GitHub requests).\n- `GIT_BRANCHES_NO_CACHE=1`: Bypass disk/memory caching and ETag.\n- `GIT_BRANCHES_REFRESH=1`: Force refresh of caches for this run.\n- `GIT_BRANCHES_PREFETCH_DETAILS=1`: Prefetch PR details (GraphQL batches).\n- `GIT_BRANCHES_SHOW_CHECKS=1`: Allow fetching Actions status (same as `--checks`). If unset, cached checks are still displayed; no fetches.\n- `GIT_BRANCHES_NO_PROGRESS=1`: Disable spinners/progress indicators.\n\n## Troubleshooting \ud83d\udee0\ufe0f\n\n- \u201cfzf not found\u201d: Install fzf and ensure it\u2019s on PATH (`brew install fzf`, `apt install fzf`, etc.).\n- \u201cNot in a git repository\u201d: Run within a git repo.\n- No icons? Install a Nerd Font and configure your terminal to use it.\n- Low API rate limit? Set `GITHUB_TOKEN` (a classic or fine-grained PAT works).\n- Homebrew says \u201cformula not in a tap\u201d: create a local tap and install:\n\n ```bash\n TAP=\"${USER}/git-branches-dev\"\n brew tap-new \"$TAP\"\n TAP_DIR=\"$(brew --repo \"$TAP\")\"\n mkdir -p \"$TAP_DIR/Formula\"\n cp Formula/git-branches.rb \"$TAP_DIR/Formula/\"\n brew install --HEAD \"$TAP/git-branches\"\n ```\n\n## Development \ud83e\uddea\n\n- Lint: `make lint` (auto-fix: `make fix`)\n- Tests: `make test` (pytest)\n- Dev loop: `make dev` (ruff fix \u2192 pytest \u2192 ruff format)\n- Format: `make format` (ruff)\n\n## License\n\nSee the repository\u2019s `LICENSE` file.\n",
"bugtrack_url": null,
"license": null,
"summary": "Interactive Git branch browser with fzf integration and GitHub PR status",
"version": "0.1.1",
"project_urls": null,
"split_keywords": [
"git",
" fzf",
" github",
" cli",
" branch-management"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c94080aa5aaec262a792c5019bb4113cab9c614245489ec113435aa0b6a36103",
"md5": "5723cd75ce6ccafb38b5e6eb52e498f6",
"sha256": "3fa4a1d2e696c54f5cca2fb6a244ac756ec51e193af30a4beb2cc21dac5cd8b3"
},
"downloads": -1,
"filename": "git_branches-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5723cd75ce6ccafb38b5e6eb52e498f6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 27956,
"upload_time": "2025-08-13T21:51:44",
"upload_time_iso_8601": "2025-08-13T21:51:44.825550Z",
"url": "https://files.pythonhosted.org/packages/c9/40/80aa5aaec262a792c5019bb4113cab9c614245489ec113435aa0b6a36103/git_branches-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f2fba18ec8e7f582ce6284e9d1eed3956cc874bb42db361674a1c448e4be0959",
"md5": "410789c6ef8dfc7815649c4c731557e9",
"sha256": "827990dd17ccdc53c2d88efd469cdf2b72102b2c29942cb5b7294e0dca83b4ea"
},
"downloads": -1,
"filename": "git_branches-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "410789c6ef8dfc7815649c4c731557e9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 32295,
"upload_time": "2025-08-13T21:51:46",
"upload_time_iso_8601": "2025-08-13T21:51:46.110159Z",
"url": "https://files.pythonhosted.org/packages/f2/fb/a18ec8e7f582ce6284e9d1eed3956cc874bb42db361674a1c448e4be0959/git_branches-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-13 21:51:46",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "git-branches"
}