gitforest
v1.4.0
Published
TUI for managing multiple Git repositories and GitHub integration
Readme
Gitforest
A terminal UI for managing multiple Git repositories and GitHub integration.
Built with Bun, TypeScript, Ink (React for CLI), and Drizzle ORM.
Features
- Project Discovery: Scan configured directories for git repos, non-git projects, and submodules
- Git Status Dashboard: See unstaged changes, unpushed/unpulled commits, sync status
- Sort & Filter: Sort by status, name, branch, sync, language, stars, forks, activity, or size; filter by text search and quick filters
- Git Operations: Init git, pull, push, fetch for single or all repos
- GitHub Integration: Create, archive, list, and clone GitHub repos using
ghfor auth and the GitHub API for data - Background Sync: Auto-fetch remotes every 5 minutes
- Caching: SQLite cache for fast subsequent runs
Installation
# From the gitforest directory
bun install
# Create config file
bun run start --init
# Edit config to add your project directories
vim ~/.config/gitforest/config.yaml
# Run gitforest
bun run startConfiguration
Config file location: ~/.config/gitforest/config.yaml. For project-local
workflows, gitforest.config.yaml in the current directory takes priority;
review that file before running Gitforest in an untrusted checkout.
directories:
- path: ~/projects
maxDepth: 2
label: Projects
- path: ~/.dotfiles
maxDepth: 3
label: Dotfiles
scan:
ignore:
- node_modules
- .git
- vendor
includeHidden: false
concurrency: 5
github:
defaultVisibility: private
display:
showSubmodules: true
sortBy: status # status | name | branch | sync | language | stars | forks | lastActivity | size
sortDirection: desc
# Optional custom commands. These execute via `sh -c` in the selected project
# directory with your normal user privileges. Confirmation defaults to true;
# set `confirm: false` only for commands you fully trust.
commands:
- name: "Run Tests"
key: "t"
command: "bun test"
confirm: trueKeyboard Shortcuts
Navigation
| Key | Action |
| --------- | ------------ |
| j / ↓ | Move down |
| k / ↑ | Move up |
| g | Go to top |
| G | Go to bottom |
Selection
| Key | Action |
| ------- | ------------------------- |
| space | Toggle selection |
| a | Select all / deselect all |
Git Operations
| Key | Action |
| --- | ------------------------------------- |
| p | Push selected repos |
| P | Pull all repos |
| f | Fetch all remotes |
| i | Init git in selected non-git projects |
GitHub Operations
| Key | Action |
| --- | ------------------------------------------- |
| c | Create GitHub repo for selected local repos |
| C | Init git if needed, then create GitHub repos |
| A | Archive selected GitHub repos |
| D | Clone selected GitHub-only repos |
View Controls
| Key | Action |
| --------- | ------------------------------------- |
| Tab | Cycle local/GitHub/all views |
| / | Enter filter mode |
| F | Show filter options |
| 0-9 | Apply quick filters |
| s / S | Cycle sort field / reverse direction |
| x | Open custom command palette |
| r | Refresh project list |
| ? | Show help |
| q | Quit |
Status Icons
| Icon | Meaning | | ---- | --------------------------- | | ✓ | Clean (no changes) | | ● | Dirty (uncommitted changes) | | ○ | Submodule | | - | Not a git repo | | ↑N | N unpushed commits | | ↓N | N unpulled commits |
Project Detection
Gitforest detects projects by looking for:
.gitdirectory (git repository).gitmodulesfile (for submodules)- Project marker files:
package.json(Node.js)Cargo.toml(Rust)pyproject.toml/setup.py(Python)go.mod(Go)Gemfile(Ruby)pom.xml/build.gradle(Java)- And more...
Requirements
Custom commands are intentionally not a security sandbox. They can read or modify anything your user account can access, so only run trusted configuration files and review commands before disabling confirmation.
Development
# Run in development mode with hot reload
bun run dev
# Run tests (recommended - handles test isolation)
bun run test
# Or run specific test groups
bun run test:unit # Unit tests only
bun run test:hooks # Hooks tests (includes isolated useKeyBindings)
bun run test:db # Database tests
bun run test:integration # Integration tests
bun run test:fast # Fast unit tests (skips scanner/git)Architecture
src/
├── app.tsx # Root Ink application
├── config/ # Config loading & validation (Zod)
├── db/ # Drizzle + SQLite cache
├── services/ # Git, GitHub, editor, and README adapters
├── github/ # GitHub auth, cache, CLI URL parsing, unified view
├── scanner/ # Directory scanning
├── components/ # Ink UI components
├── hooks/ # React hooks
├── state/ # State management
└── types/ # TypeScript types