README
¶
Git Context Switcher
A powerful command-line tool for managing multiple Git configuration profiles. Seamlessly switch between different Git identities (work, personal, school, etc.) with a single command.
Features
- Multiple Profiles - Create and manage unlimited Git configuration profiles
- Instant Switching - Switch between profiles with a single command
- Global Settings - Define shared configuration across all profiles
- URL Rewrites - Configure Git URL rewrites per profile (SSH <-> HTTPS)
- Safe Operations - Automatic backups before switching profiles
- Interactive Setup - Guided profile creation with prompts
- Colored Output - Beautiful, easy-to-read CLI output
- YAML Configuration - Simple, human-readable configuration format
Installation
Quick Install (Recommended)
Using Go Install
go install github.com/techquestsdev/git-context@latest
Then run with: git-context
Using Homebrew (MacOS/Linux)
brew tap techquestsdev/tap
brew install git-context
Download Binary
Download the latest release for your platform from the Releases page:
- Linux (amd64, arm64)
- MacOS (Intel, Apple Silicon)
- Windows (amd64)
# Example: Download and install on Linux/MacOS
curl -L https://github.com/techquestsdev/git-context/releases/latest/download/git-context_Linux_x86_64.tar.gz | tar xz
sudo mv git-context /usr/local/bin/
Build from Source
Prerequisites
- Go 1.25 or higher
- Git 2.0 or higher
- Make (optional, for using Makefile commands)
Clone and Build
# Clone the repository
git clone https://github.com/techquestsdev/git-context.git
cd git-context
# Download dependencies
go mod download
# Build the application
go build -o bin/git-context
# Install to your system
make install
# Or without Make:
go install
# Verify installation
git-context --version
Usage
Quick Start Guide
1. Initialize Configuration
First-time setup:
# Initialize git-context
git-context init
This creates ~/.config/git-context/config.yaml.
Add Your First Profile
# Add a new profile named 'work'
git-context add work
You'll be prompted for:
- Git Name - Your full name
- Git Email - Your email address
- GPG Signing Key (optional) - Your GPG key ID
- URL rewrites (optional) - SSH/HTTPS URL conversions
3. List All Profiles
# List available profiles
git-context list
Output:
=== Available Profiles ===
Profile Email Status
------- ----- ------
work andre@work.com ● (active)
personal andre@personal.com
university andre@university.edu
4. Switch Between Profiles
# Switch to 'personal' profile
git-context switch personal
# Switch back to the previous profile
git-context switch -
Output:
=== Switching to Profile: personal ===
ℹ Backed up git config to /Users/andre/.gitconfig.bak
✓ Switched to profile 'personal'
ℹ User: Andre Nogueira <andre@personal.com>
5. Show Current Profile
# Display the active profile
git-context current
6. Show Profile Details
# Show details of 'work' profile
git-context show work
7. Remove a Profile
# Remove 'university' profile
git-context remove university
All Available Commands
| Command | Description |
|---|---|
git-context init |
Initialize configuration |
git-context add <name> |
Create a new profile |
git-context switch <name|-> |
Switch to a profile |
git-context list |
List all profiles |
git-context current |
Show active profile |
git-context show <name> |
Show profile details |
git-context remove <name> |
Delete a profile |
git-context dir add <path> <profile> |
Assign a directory to a profile (auto-applied via includeIf) |
git-context dir remove <path> |
Remove a directory assignment |
git-context dir list |
List all directory assignments |
git-context --help |
Show help |
git-context --version |
Show version |
Directory-Based Profiles
Assign filesystem paths to profiles so git applies the right identity automatically when you're inside them — no need to remember to switch.
# Make 'work' the default profile (used everywhere unless overridden)
git-context switch work
# Assign specific directories to other profiles
git-context dir add ~/projects/personal personal
git-context dir add ~/Mollie work
# See all assignments
git-context dir list
Under the hood git-context generates one gitconfig file per profile under ~/.config/git-context/profiles/ and rewrites ~/.gitconfig as a thin manifest of [include] and [includeIf "gitdir:..."] blocks that git-context regenerates on every mutating command. The YAML at ~/.config/git-context/config.yaml is always the source of truth.
Note: git-context owns
~/.gitconfigend-to-end — don't rungit config --globaldirectly. Edit the YAML or use the CLI instead.
Configuration
The configuration is stored in YAML format at ~/.config/git-context/config.yaml.
Configuration Structure
global:
# Shared settings across all profiles
<section>:
<key>: <value>
profiles:
<profile-name>:
user:
name: "Your Name"
email: "your.email@example.com"
signingkey: "GPG_KEY_ID" # optional
url:
- pattern: "ssh://git@gitlab.com/"
insteadOf: "https://gitlab.com/"
# Any other Git config sections...
Example Configuration
global:
core:
pager: delta
editor: nvim
push:
autoSetupRemote: true
merge:
conflictstyle: diff3
commit:
gpgsign: true
gpg:
program: /usr/local/bin/gpg
pull:
rebase: true
profiles:
work:
user:
name: "Andre Nogueira"
email: "aanogueira@techquests.dev"
signingkey: "A0A90F4231D8B028"
url:
- pattern: "git@git.techquests.dev/"
insteadOf: "https://git.techquests.dev/"
- pattern: "ssh://git@github.com/"
insteadOf: "https://github.com/"
http:
postBuffer: 157286400
personal:
user:
name: "Andre Nogueira"
email: "aanogueira@protonmail.com"
signingkey: "B1C2D3E4F5G6H7I8"
url:
- pattern: "ssh://git@github.com/"
insteadOf: "https://github.com/"
university:
user:
name: "Andre Nogueira"
email: "aanogueira@university.edu"
signingkey: "C1D2E3F4G5H6I7J8"
Global vs Profile-Specific Settings
- Global settings are applied to all profiles
- Profile-specific settings override global settings
- Any Git configuration section can be used (core, push, merge, etc.)
Common Configuration Sections
| Section | Purpose | Parameters |
|---|---|---|
add |
Add settings | <key>: <value> |
alias |
Create shortcuts for commands | <alias>: <command> |
branch |
Branch management | <key>: <value> |
column |
Column layout settings | <key>: <value> |
commit |
Commit message templates | <key>: <value> |
core |
Core Git settings | <key>: <value> |
custom |
Custom settings | <key>: <value> |
delta |
Delta pager settings | <key>: <value> |
diff |
Diff settings | <key>: <value> |
feature |
Feature settings | <key>: <value> |
fetch |
Fetch settings | <key>: <value> |
gpg |
GPG settings | <key>: <value> |
http |
HTTP settings | <key>: <value> |
init |
Initialization settings | <key>: <value> |
interactive |
Interactive settings | <key>: <value> |
maintenance |
Maintenance settings | <key>: <value> |
merge |
Merge settings | <key>: <value> |
pull |
Pull settings | <key>: <value> |
push |
Push settings | <key>: <value> |
rebase |
Rebase settings | <key>: <value> |
rerere |
Rerere settings | <key>: <value> |
pager |
Pager settings | <key>: <value> |
tag |
Tag settings | <key>: <value> |
url |
URL settings | <key>: <value> |
user |
User settings | <key>: <value> |
Use Cases
Scenario 1: Work vs Personal Repositories
Separate professional and personal Git identities:
# Create work profile with company email
git-context add work
# Enter: Your Name, you@company.com, work-gpg-key
# Create personal profile with personal email
git-context add personal
# Enter: Your Name, you@personal.com, personal-gpg-key
# Switch based on what you're working on
git-context switch work # For company projects
git-context switch personal # For personal projects
Scenario 2: Multiple Companies/Clients
Manage identities for different employers or clients:
git-context add client-a
git-context add client-b
git-context add freelance
# Switch when changing projects
git-context switch client-a
Scenario 3: Academic and Professional
Separate academic credentials from professional:
git-context add university # .edu email, academic GPG key
git-context add work # Company email, work GPG key
Scenario 4: Different URL Rewrites
Configure SSH access for different Git hosts:
profiles:
work:
url:
- pattern: "ssh://git@git.company.com/"
insteadOf: "https://git.company.com/"
personal:
url:
- pattern: "ssh://git@github.com/"
insteadOf: "https://github.com/"
Safety Features
- Automatic Backups - Before switching profiles, current Git config is backed up to
~/.gitconfig.bak - Confirmation Prompts - Destructive operations require user confirmation
- Validation - Profiles are validated before being applied
- Error Handling - Clear error messages guide you when something goes wrong
- Non-Destructive Init -
initcommand preserves existing profiles
Troubleshooting
Config File Not Found
Solution: Initialize the configuration:
git-context init
Profile Not Found
Solution: Check available profiles:
git-context list
Git Config Not Updating
Problem: No write permissions to ~/.gitconfig
Solution: Check file permissions:
ls -la ~/.gitconfig
chmod 644 ~/.gitconfig # If needed
Restore from Backup
If something went wrong, restore from the automatic backup:
cp ~/.gitconfig.bak ~/.gitconfig
Profile Already Exists
Problem: git-context init reports profiles exist
Solution: This is expected! The init command now preserves existing profiles instead of clearing them.
Testing
The project has comprehensive test coverage and zero linting issues, leveraging Go's testing framework and golangci-lint for code quality.
Run Tests
# Run all tests
make test
# Or:
go test -v
# Run tests with coverage
make test-coverage
# Or:
go test -v -cover
# Generate detailed coverage report
make test-coverage-view
# Or:
go test -coverprofile=coverage.out
go tool cover -html=coverage.out
# Run benchmarks
make bench
Linting and Formatting
# Run linter
make lint
# Auto-fix linting issues
make lint-fix
# Format code
make fmt
# Run vet
make vet
# Check everything (format + lint + test)
make check
# Run all checks and build
make all
Test Categories
- Configuration Management - Profile CRUD, merging, persistence
- Git Operations - Config file parsing, URL rewrites, backups
- UI Components - Colored output, tables, formatting
- Command Integration - Profile operations, error handling
- Edge Cases - Invalid YAML, missing files, error paths
Architecture
Project Structure
git-context/
├── cmd/ # CLI commands
│ ├── root.go # Root command & init
│ ├── add.go # Add profile command
│ ├── switch.go # Switch profile command
│ ├── list.go # List profiles command
│ ├── remove.go # Remove profile command
│ ├── current.go # Show current profile
│ ├── show.go # Show profile details
│ └── cmd_test.go # Command tests
├── internal/
│ ├── config/
│ │ ├── config.go # Configuration management
│ │ ├── config_test.go # Config tests
│ │ ├── paths.go # Path management
│ │ └── paths_test.go # Path tests
│ ├── git/
│ │ ├── git.go # Git operations
│ │ └── git_test.go # Git tests
│ └── ui/
│ ├── output.go # UI/UX helpers
│ └── output_test.go # UI tests
├── bin/ # Build output
├── main.go # Entry point
├── go.mod # Go module dependencies
├── go.sum # Dependency checksums
└── README.md # This file
Design Principles
- Separation of Concerns - Clear boundaries between CLI, config, git, and UI layers
- Testability - High test coverage with isolated unit tests
- User Experience - Colored output, clear messages, confirmation prompts
- Safety First - Automatic backups, validation, error handling
Dependencies
- github.com/spf13/cobra - CLI framework
- github.com/manifoldco/promptui - Interactive prompts
- github.com/fatih/color - Colored terminal output
- gopkg.in/yaml.v3 - YAML parsing and serialization
Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Before Submitting
- Ensure all tests pass (
go test -v ./...) - Maintain or improve code coverage
- Follow existing code style
- Add tests for new features
- Update documentation as needed
Development Commands
The project includes a comprehensive Makefile with the following commands:
# Show all available make commands
make help
# Development
make run # Run the application
make build # Build the binary
make install # Install to GOPATH/bin
# Testing
make test # Run tests with race detection
make test-verbose # Run tests with verbose output
make test-coverage # Generate coverage report
make test-coverage-view # Generate and open coverage report in browser
make bench # Run benchmarks
# Code Quality
make lint # Run golangci-lint
make lint-fix # Run linter with auto-fix
make fmt # Format code with gofmt
make vet # Run go vet
make check # Run all checks (fmt, vet, lint, test)
# Dependencies
make deps # Download dependencies
make deps-upgrade # Upgrade all dependencies
make deps-verify # Verify dependencies
# Cleanup
make clean # Remove build artifacts and coverage reports
make clean-all # Full cleanup including Go cache
# Utilities
make mod-graph # Show module dependency graph
make mod-why PKG=... # Show why a package is needed
make version # Show Go version
# All-in-one
make all # Run fmt, lint, test, and build
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Cobra for the excellent CLI framework
- Bubble Tea ecosystem for inspiration
- PromptUI for interactive prompts
Contact
André Nogueira - @aanogueira
Project Link: https://github.com/techquestsdev/git-context
Made with ❤️ and Go
Documentation
¶
There is no documentation for this package.