Warning
🚧 Do Not Use — History Will Be Rewritten 🚧
This repo is undergoing major restructuring as we selectively open-source internal tools built at Idea Crafters LLC. Git history will be force-pushed and rewritten multiple times. Do not fork, clone, or depend on this repo in any capacity until we tag a stable release.
A Git subcommand that wraps git worktree with deterministic, isolated, and reproducible multi-branch development environments.
git-hop eliminates the friction of managing multiple Git worktrees by automatically organizing worktrees, allocating resources (ports, volumes, networks), and providing lifecycle management for Docker environments. Work on multiple branches in parallel without port conflicts, manual configuration, or lost context.
Perfect for:
- Multi-branch development workflows
- Testing multiple PRs locally
- Feature branch isolation
- Parallel development with Docker services
Not for:
- Distributed team orchestration
- Production deployment management
- Multi-tenant setups
- Monorepo optimization (see Git's native monorepo support)
- 🚀 Automatic Navigation - Optional shell integration for seamless worktree switching
- 🔗 Smart Symlinks -
currentsymlink always points to your last worktree - 🐳 Docker Integration - Isolated environments with deterministic port allocation
- 📦 Dependency Management - Automatic npm/yarn/pnpm installation per worktree
- 🔄 State Tracking - Track all worktrees across your system
- 🛠️ Zero Config - Sensible defaults, works out of the box
From source (requires Go 1.21+)
git clone https://github.com/jadb/git-hop.git
cd git-hop
make build
sudo mv git-hop /usr/local/bin/Verify installation:
git hop --versionFrom go install
go install github.com/jadb/git-hop@latestInitialize git-hop in an existing repository:
cd /path/to/my/repo
git hop initThe interactive setup will guide you through:
- Converting to bare repo + worktrees (recommended)
- Setting up initial branch worktree
- Creating hop.json configuration
Then create a worktree for a feature branch:
git hop add feature-x
cd feature-xOptional: Install shell integration for automatic directory switching:
git hop install-shell-integration
# Now use: git-hop feature-x (automatically cd to worktree)You now have:
- A clean worktree for
feature-x - Deterministic ports allocated (no conflicts)
- Docker environment configured (if docker-compose.yml exists)
- Full isolation from other branches
- (Optional) Automatic navigation with
git-hopcommand
List all worktrees:
git hop listStop the environment:
git hop env stop| Command | Description |
|---|---|
git hop init |
Initialize git-hop in a repository (interactive setup) |
git hop <branch> |
Navigate to an existing worktree (updates current symlink) |
git hop add <branch> |
Create a new worktree and environment for a branch |
git hop list |
List all managed worktrees and their status |
git hop status |
Show status of current worktree or hub |
git hop remove <target> |
Remove a worktree, hopspace, or hub |
git hop prune |
Clean up orphaned worktrees and hubs |
git hop doctor |
Check and repair environment issues |
Enable automatic directory switching when hopping between worktrees:
| Command | Description |
|---|---|
git hop install-shell-integration |
Install shell wrapper for auto-cd (bash/zsh/fish) |
git hop uninstall-shell-integration |
Remove shell wrapper function |
git-hop <branch> |
Navigate and auto-cd (requires shell integration) |
Manage Docker services and resources:
git hop env start # Start Docker services for current worktree
git hop env stop # Stop Docker servicesAvailable on all commands:
--config <path> # Path to config file
--json # Output in JSON format
--porcelain # Machine-readable output
--quiet, -q # Suppress output
--verbose, -v # Verbose output
--force # Bypass safety checks
--dry-run # Preview changes without applying
--global, -g # Use global hopspace instead of local
--git-domain <domain> # Git domain for shorthand notation (default: github.com)
--help, -h # Show command help
--version # Show version informationA hub is a directory that serves as your local working context. It contains:
- A
hop.jsonconfiguration file tracking all worktrees - A
.gitreference to the bare repository - Direct access to worktrees via paths stored in config
my-repo/ # Hub directory (local context)
.git # Bare repository reference
hop.json # Hub configuration (tracks worktree paths)
The hub's hop.json maintains references to all worktrees with their full paths, allowing you to quickly switch between branches without manual path management.
A hopspace is the canonical storage location for all worktrees of a repository. Located at:
$GIT_HOP_DATA_HOME/<domain>/<org>/<repo>/
hop.json # Hopspace configuration
ports.json # Port allocations
volumes.json # Volume allocations
feature-x/ # Actual worktree directory
feature-y/
...
All worktrees for a repository reference the same hopspace, ensuring consistency.
Ports, volumes, and networks are derived from stable hashing:
- Same branch = same ports across worktrees (reproducible)
- Different branches = different ports (no conflicts)
- Predictable allocation (no manual configuration)
Example: branch feature-x always gets ports 11500-11505 if not already assigned.
Configuration follows a hierarchy (higher priority overrides lower):
- Environment variables
- Command-line flags
$XDG_CONFIG_HOME/git-hop/config.json(global)- Hub-level
hop.json - Hopspace-level
hop.json
Create $XDG_CONFIG_HOME/git-hop/config.json:
{
"auto_env_start": "detect",
"port_base": 10000,
"port_limit": 5000,
"defaults": {
"worktree_location": "hops"
}
}Configuration options:
auto_env_start- Auto-start Docker services (true,false, or"detect"to start only if services exist)port_base- Starting port for allocation (default: 10000)port_limit- Maximum ports available (default: 5000)defaults.worktree_location- Directory for storing worktrees (default:hops)
GIT_HOP_DATA_HOME # Hopspace storage location (OS-specific default)
GIT_HOP_CONFIG_HOME # Config directory (default: $XDG_CONFIG_HOME/git-hop)
GIT_HOP_CACHE_DIR # Cache directory (default: $XDG_CACHE_HOME/git-hop)
GIT_HOP_LOG_LEVEL # Log level: debug, info, warn, error (default: info)- Linux/Unix:
~/.local/share/git-hop - macOS:
~/Library/Application Support/git-hop - Windows:
%LOCALAPPDATA%\git-hop
# From hub directory
git hop add feature-new-ui
# Hop to the new worktree
cd feature-new-ui# List all worktrees
git hop list
# Switch to existing worktree (via filesystem)
cd ../feature-existing
# Or use your shell navigation (e.g., cd /path/to/hop/feature-existing)# Start Docker services for current worktree
git hop env start
# Stop services
git hop env stop
# Auto-start on worktree creation
git hop config auto_env_start detect# Show current worktree status
git hop status
# Show all repositories and worktrees
git hop status --all
# Output as JSON
git hop status --json# Remove a single worktree
git hop remove feature-old
# Clean up orphaned worktrees (deleted on filesystem)
git hop prune
# Check and fix issues
git hop doctor --fixSymptom: Docker containers fail to start due to port conflicts.
Solution:
git hop doctorThe doctor command detects conflicting port allocations and helps resolve them.
Symptom: git hop list shows worktrees that no longer exist.
Solution:
git hop pruneThis removes worktrees from state if their directories don't exist on the filesystem.
Symptom: git hop env start fails or services don't start.
Steps:
- Verify Docker is running:
docker ps - Check environment status:
git hop status - Review docker-compose.yml in worktree:
cat docker-compose.yml - Check logs:
git hop status --verbose
Symptom: "Failed to load hopspace" error.
Solution:
git hop doctor --fixThis initializes missing hopspace directories and configurations.
Symptom: "Not in a git-hop hub" error.
Solution:
Run git hop init to convert your repository:
cd /path/to/repo
git hop initgit-hop installs lightweight Git hook wrappers that integrate with your workflow:
pre-worktree-add- Before creating a worktreepost-worktree-add- After creating a worktreepre-env-start- Before starting environmentpost-env-start- After starting environmentpre-env-stop- Before stopping environmentpost-env-stop- After stopping environment
- Repo-level hop hook override (if exists)
- Hopspace-level hook (if exists)
- Global hook (if exists)
- Built-in default behavior
Place hooks in $GIT_HOP_CONFIG_HOME/hooks/ or hopspace-specific directories to customize behavior.
See Hooks System for detailed examples.
Control output with flags:
# Human-readable (default)
git hop list
# JSON format
git hop list --json
# Machine-readable (porcelain)
git hop list --porcelain
# Suppress all output
git hop status --quietManage multiple repositories with different configurations:
# Clone repo 1
git hop https://github.com/org/repo1.git
cd org/repo1
git hop init
# Clone repo 2 with custom settings
git hop https://github.com/org/repo2.git
cd org/repo2
git hop init
git hop config port_base 20000Each repository has its own hopspace with independent resource allocation.
Repositories with docker-compose.yml automatically detect and allocate resources:
# docker-compose.yml in worktree
version: '3'
services:
api:
ports:
- "${API_PORT}:3000"
db:
ports:
- "${DB_PORT}:5432"git-hop automatically injects ${API_PORT} and ${DB_PORT} based on branch allocations.
make build # Build the binary
make install # Install to /usr/local/bin
make test # Run tests
make lint # Run linter
make fmt # Format code
make clean # Clean build artifactsgit-hop/
cmd/ # Command implementations
internal/
cli/ # CLI framework and root command
hop/ # Core worktree and hopspace logic
config/ # Configuration management
docker/ # Docker integration
state/ # State file management
services/ # Environment and dependency services
output/ # Output formatting and styling
docs/ # Documentation and guides
main.go # Entry point
Makefile # Build and test targets
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make changes and add tests
- Run tests:
make test - Commit with clear messages
- Push and open a pull request
make test # Run all tests
go test ./cmd -v # Test specific package
go test -run TestName # Run specific testThe default go test ./... covers tier-1 (unit) and tier-2 (local-git
e2e) tests. Tier-3 docker e2e tests are gated behind the dockere2e
build tag and run nightly via .github/workflows/dockere2e.yml. To run
them locally:
go test -tags dockere2e ./test/e2e/docker/...See docs/testing.md for the full testing architecture, CI workflow split, the xrr-aware binary contract, and common gotchas.
For detailed information, see:
- Configuration - Directory structure, config files, environment variables, XDG compliance
- Dependency Sharing - How worktrees share dependencies to save disk space
- Hooks System - Lifecycle hooks for customizing worktree and environment behavior
- Error Recovery - Understanding and fixing state issues with the doctor command
- Package Manager Overrides - Custom dependency installation per branch
- Testing - Test tiers, CI workflow split, dockere2e gate, xrr-aware test runtime
Q: Can I use git-hop with a monorepo?
A: Yes, but standard Git tools may be more suitable. git-hop shines with multi-branch development in single repositories.
Q: Do I need Docker?
A: No. Docker is optional. git-hop works perfectly for non-containerized projects.
Q: How much disk space do worktrees use?
A: Each worktree is a separate directory with checked-out files. git-hop optimizes with dependency sharing and caching. See Dependency Sharing.
Q: Can I move a hub or hopspace?
A: Yes. Hub paths are flexible. Hopspace paths should be updated in configuration. Use git hop doctor after moving.
Q: What Git versions are supported?
A: Git 2.7+ (worktree support was added in Git 2.5, git-hop requires 2.7+ for full compatibility).
Q: How do I uninstall git-hop?
A: Remove the binary and clean up data directories:
sudo rm /usr/local/bin/git-hop
rm -rf ~/.local/share/git-hop # Linux
rm -rf ~/Library/Application\ Support/git-hop # macOSState and config files remain for recovery if needed.
- Issues: Report bugs at GitHub Issues
- Discussions: Ask questions at GitHub Discussions
- Documentation: See docs/ directory for guides and troubleshooting
MIT © 2025 Jad Bitar