A terminal UI for organizing git changes into changelists and shelves — like IntelliJ IDEA's changelist system, but for any repo and any editor.
Other projects:
- Color Manipulation — Color toolkit for JetBrains IDEs with 30+ format conversions
- Vector Drawable Thumbnails — Thumbnail previews of Android Vector Drawables in JetBrains IDEs
You're working on a feature. You notice a typo. You fix it. Now your git diff mixes the typo fix with the feature work, and you have to mentally separate them at commit time — or worse, you commit them together.
IDEs like IntelliJ solve this with changelists — logical groups that let you organize your uncommitted changes by intent, not by time. But if you work in VS Code, Neovim, or any other editor, you don't get this.
gitshelf brings changelists and shelves to your terminal.
- Changelists — Group your changed files by purpose. Commit "bug fix" and "refactor" separately, even if you worked on both at the same time.
- Shelves — Save changes for later without committing. Like
git stash, but named, browsable, and you can shelve individual files instead of everything. - Selective commit — Check the files you want, write a message, done. No staging gymnastics.
- Dirty detection — Know when files changed since you last looked at a changelist.
- Push & pull — Without leaving the TUI.
- Full diff viewer — Syntax-highlighted, scrollable, with word wrap toggle.
- Worktree support — Browse and manage changelists, shelves, and files across all your worktrees from a single instance.
- Git log — Every git command the app runs is visible. Nothing hidden.
brew tap ignaciotcrespo/tap
brew install gitshelfgo install github.com/ignaciotcrespo/gitshelf/cmd/gitshelf@latestGrab the latest release for your platform from GitHub Releases.
cd your-git-repo
gitshelfThat's it. The app detects the repo root automatically.
Six panels: Changelists, Shelves, and Worktrees stacked on the left, Files in the center, Diff on the right, and Git Log spanning the full width at the bottom.
When files change after being assigned to a changelist, they're marked with * and highlighted in yellow. Press B to accept the current state as the new baseline.
Save changes for later without committing. Browse shelf contents and diffs before restoring.
If you use git worktrees, gitshelf lets you manage all of them from wherever you launched it. Press 6 to open the Worktrees panel, then navigate with arrow keys — the changelists, shelves, files, and diffs update automatically as you move between worktrees.
Each worktree has its own independent .gitshelf/ directory, so changelists and shelves are completely isolated.
What you can do:
- Manage changelists and shelves per worktree. Navigate to any worktree and see its changelists, shelves, and uncommitted files — all without leaving the app or
cd-ing between directories. - Copy changelists between worktrees. Press
Wto copy a changelist, navigate to another worktree, pressVto paste. Three paste modes:- Full content — copies the actual file contents from the source worktree
- Apply diff — generates a patch from the source and applies it
- Only changelist — just creates the changelist grouping without modifying files (useful when both worktrees already have the same files changed)
Example: copying a changelist between worktrees
You're working on a feature in the main worktree and realize some of the changes belong in your hotfix worktree:
┌ Changelists ──┐ ┌ Files ─────────┐
│ ▸ Changes │ │ main.go │ 1. Select the changelist
│ Bug fix ◄──┼─┼── W to copy │ 2. Press W to copy it
│ │ │ │
├───────────────┤ │ │
│ Shelves │ │ │
│ │ │ │
├───────────────┤ │ │
│ Worktrees │ │ │
│ main ● │ │ │
│ ▸ hotfix ◄────┼─┼── navigate │ 3. Move to the hotfix worktree
└───────────────┘ └────────────────┘
┌ Changelists ──┐ ┌ Files ─────────┐
│ ▸ Changes │ │ config.go │ 4. Press V to paste
│ Bug fix ◄──┼─┼── V to paste │ 5. Choose a paste mode
│ │ │ │
└───────────────┘ └────────────────┘
When you need to save everything at once — switching context, going to a meeting, or just want a checkpoint — press S on the Changelists panel. This shelves every changelist with changed files in one go, creating a grouped snapshot:
Before S After S
┌ Changelists ──┐ ┌ Changelists ──┐
│ ▸ Changes │ 3 files │ ▸ Changes │ no files
│ Feature │ 2 files │ Feature │ no files
│ Refactor │ 1 file │ Refactor │ no files
├───────────────┤ ├───────────────┤
│ Shelves │ │ Shelves │
│ │ │ ┌ Changes │ ─┐
│ │ │ ├ Feature │ ├ snapshot group
│ │ │ └ Refactor │ ─┘
└───────────────┘ └───────────────┘
The ┌├└ markers show which shelves belong together. To restore them all, select any shelf in the group and press U:
Before U After U
┌ Changelists ──┐ ┌ Changelists ──┐
│ ▸ Changes │ no files │ ▸ Changes │ 3 files
│ Feature │ no files │ Feature │ 2 files
│ Refactor │ no files │ Refactor │ 1 file
├───────────────┤ ├───────────────┤
│ Shelves │ │ Shelves │
│ ┌ Changes │ ─┐ │ ┌ Changes │ ─┐ kept
│ ├ Feature │ ├ select any │ ├ Feature │ ├ for
│ └ Refactor │ ─┘ press U │ └ Refactor │ ─┘ safety
└───────────────┘ └───────────────┘
The shelves are kept after unshelving — drop them manually with d when you're sure you don't need them anymore.
The UI has six panels, accessible by number keys:
| # | Panel | Shows |
|---|---|---|
| 1 | Changelists | Your logical groups of changes |
| 2 | Shelves | Saved change sets (like named stashes) |
| 3 | Files | Files in the selected changelist or shelf |
| 4 | Diff | Diff of the selected file |
| 5 | Git Log | Every git command the app executed |
| 6 | Worktrees | All worktrees — navigate to browse their changelists and shelves |
Press 4 or 5 to cycle a panel through normal → maximized → hidden. Press 6 to toggle the Worktrees panel between normal and minimized.
See docs/keybindings.md for the full list. Press ? in the app for an in-app reference.
Quick overview: n new changelist, space select files, c commit, s shelve, m move files, p/P push/pull, y copy patch.
gitshelf is not a git client. It's a change organizer — it groups your uncommitted files into logical changelists and lets you shelve them for later. The commit, amend, push, and pull commands are there for convenience so you don't have to leave the TUI for basic operations.
For anything beyond that — merge conflicts, rebasing, cherry-picking, bisecting, or any advanced git workflow — use a proper git tool like lazygit, tig, or the git CLI directly.
See docs/design.md for details on changelists, shelves, dirty detection, data storage, and design decisions.
git clone https://github.com/ignaciotcrespo/gitshelf.git
cd gitshelf
./build.sh
./gitshelf --versionBuilt with Bubbletea by Charm. Inspired by IntelliJ IDEA's changelist system and lazygit's approach to making git approachable from the terminal.


