GLF - GitLab Fuzzy Finder
β‘ Fast CLI tool for instant fuzzy search across self-hosted GitLab projects using local cache.

β¨ Features
- β‘ Lightning-fast fuzzy search with local caching
- π¨ Interactive TUI with adaptive color scheme
- π Multi-token search - Search with spaces:
"api storage" finds projects with both terms
- π§ Smart ranking - Frequently selected projects automatically appear first
- π Parallel pagination - 5-8x faster sync with concurrent API requests
- π Auto-sync on startup - Projects refresh in background while you search
- π Live sync - Press
Ctrl+R to manually refresh anytime (non-blocking)
- π Clean activity indicator - Single circle (β/β) shows sync and history loading status
- βοΈ Easy configuration via interactive wizard or YAML
- π Cross-platform builds for macOS, Linux, and Windows
- π Verbose logging with progress indicators for troubleshooting
π Quick Start
Installation
Homebrew (macOS/Linux)
The easiest way to install GLF on macOS or Linux:
# Add the tap
brew tap igusev/tap
# Install GLF
brew install glf
# Update to latest version
brew upgrade glf
From Source
# Clone the repository
git clone https://github.com/igusev/glf.git
cd glf
# Build and install
make install
Pre-built Binaries
Download the latest release for your platform from the releases page.
Configuration
Run the interactive configuration wizard:
glf --init
This will prompt you for:
- GitLab instance URL (e.g.,
https://gitlab.example.com)
- Personal Access Token (with
read_api scope)
- API timeout (default: 30 seconds)
Configuration is saved to ~/.config/glf/config.yaml.
To reset and reconfigure:
glf --init --reset
Manual Configuration
Create ~/.config/glf/config.yaml:
gitlab:
url: "https://gitlab.example.com"
token: "your-personal-access-token"
timeout: 30 # optional, defaults to 30 seconds
cache:
dir: "~/.cache/glf" # optional
Environment Variables
You can also use environment variables:
export GLF_GITLAB_URL="https://gitlab.example.com"
export GLF_GITLAB_TOKEN="your-token-here"
export GLF_GITLAB_TIMEOUT=30 # optional
Creating a Personal Access Token
- Go to your GitLab instance
- Navigate to User Settings β Access Tokens
- Create a new token with
read_api scope
- Copy the token and use it in
glf --init
Sync Projects
Fetch projects from GitLab and build local cache:
glf sync
Search Projects
Interactive Mode (Default)
# Launch interactive fuzzy finder
glf
# Start with initial query
glf backend
Navigation:
β/β - Navigate through results
Enter - Select project
Ctrl+R - Manually refresh/sync projects from GitLab
Ctrl+X - Exclude/un-exclude project from search results
Ctrl+H - Toggle showing excluded projects
? - Toggle help text
Esc/Ctrl+C - Quit
- Type to filter projects in real-time
Activity Indicator:
β - Idle (nothing happening)
β (green) - Active: syncing projects or loading selection history
β (red) - Error: sync failed
- Auto-sync runs on startup, manual sync available with
Ctrl+R
π Usage
Commands
glf [query] Search projects (default: interactive TUI)
glf --init Configure GitLab connection
glf --init --reset Reset and reconfigure GitLab connection
glf --sync Sync projects from GitLab to local cache
glf --help Show help
Flags
--init Run interactive configuration wizard
--reset Reset configuration and start from scratch (use with --init)
-o, --go Auto-select first result and open in browser
-g, --open Alias for --go (for compatibility)
-s, --sync Synchronize projects cache
--full Force full sync (use with --sync)
-v, --verbose Enable verbose logging
--scores Show score breakdown for debugging ranking
Examples
# Interactive search
glf
# Search with pre-filled query
glf microservice
# Multi-token search (matches projects with all terms)
glf api storage # Finds projects containing both "api" AND "storage"
glf user auth service # Finds projects with all three terms
# Auto-select first result and open in browser
glf ingress -o # Opens first "ingress" match
glf api -g # Same as -o (alias for compatibility)
# Open current Git repository in browser
glf .
# Sync projects from GitLab
glf --sync # Incremental sync
glf --sync --full # Full sync (removes deleted projects)
# Verbose mode for debugging
glf sync --verbose
# Show ranking scores for debugging
glf --scores
# Configure GitLab connection
glf --init
# Reset and reconfigure
glf --init --reset
Smart Ranking
GLF learns your selection patterns and automatically boosts frequently used projects:
- First time: Search
"api" β Select myorg/api/storage
- Next time: Search
"api" β myorg/api/storage appears first!
- The more you select a project, the higher it ranks
- Query-specific boost: projects selected for specific search terms rank higher for those terms
- Recent selections get extra boost (last 7 days)
History is stored in ~/.cache/glf/history.gob and persists across sessions.
π§ Development
Building
# Build for current platform
make build
# Build for all platforms
make build-all
# Build for specific platform
make build-linux
make build-macos
make build-windows
# Create release archives
make release
Testing
# Run tests
make test
# Run tests with coverage
make test-coverage
# Format code
make fmt
# Run linters
make lint
Project Structure
glf/
βββ cmd/glf/ # CLI entry point
β βββ main.go # Main command and search logic
βββ internal/
β βββ config/ # Configuration handling
β βββ gitlab/ # GitLab API client
β βββ history/ # Selection frequency tracking
β βββ index/ # Description indexing (Bleve)
β βββ logger/ # Logging utilities
β βββ search/ # Combined fuzzy + full-text search
β βββ sync/ # Sync logic
β βββ tui/ # Terminal UI (Bubbletea)
β βββ types/ # Shared types
βββ Makefile # Build automation
βββ README.md
βοΈ Configuration Options
GitLab Settings
| Option |
Description |
Default |
Required |
gitlab.url |
GitLab instance URL |
- |
Yes |
gitlab.token |
Personal Access Token |
- |
Yes |
gitlab.timeout |
API timeout in seconds |
30 |
No |
Cache Settings
| Option |
Description |
Default |
Required |
cache.dir |
Cache directory path |
~/.cache/glf |
No |
Exclusions
| Option |
Description |
Default |
Required |
exclusions |
List of project paths to exclude |
[] |
No |
Example with exclusions:
gitlab:
url: "https://gitlab.example.com"
token: "your-token"
exclusions:
- "archived/old-project"
- "deprecated/legacy-api"
Excluded projects can be toggled with Ctrl+X in the TUI or hidden/shown with Ctrl+H.
π Troubleshooting
Connection Issues
# Use verbose mode to see detailed logs
glf sync --verbose
Common issues:
- Invalid GitLab URL: Verify URL in config
- Token expired: Regenerate token in GitLab
- Network timeout: Increase timeout in config
- Insufficient permissions: Ensure token has
read_api scope
Cache Issues
# Check cache location
ls -la ~/.cache/glf/
# Clear cache and re-sync
rm -rf ~/.cache/glf/
glf sync
Configuration Issues
# Reconfigure GitLab connection
glf --init
# Reset and reconfigure from scratch
glf --init --reset
# Check current configuration
cat ~/.config/glf/config.yaml
GLF uses intelligent parallel pagination to dramatically improve sync performance:
| Metric |
Before |
After |
Improvement |
| 648 projects |
~26 seconds |
~3-5 seconds |
5-8x faster |
| 2000 projects |
~74 seconds |
~7-8 seconds |
10x faster |
How it works:
- First request discovers total page count
- Launches up to 10 concurrent requests for remaining pages
- Uses goroutines with semaphore-based rate limiting
- Results are collected via channels and reassembled in order
Verbose mode shows real-time progress:
$ glf sync --verbose
[DEBUG] Total pages: 7, Total projects: 648
[DEBUG] Starting parallel fetch: 7 pages with max 10 concurrent requests
[DEBUG] Fetched page 2/7 (28%)
[DEBUG] Fetched page 7/7 (100%)
[DEBUG] Parallel fetch completed in 3.2s: fetched 648 projects from 7 pages
β Successfully fetched 648 projects
π License
MIT License - see LICENSE file for details.
π€ Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
π Acknowledgments