Git ID Switcher
🎯 Why Git ID Switcher?While many Git identity switchers exist, Git ID Switcher solves the complex problems that others ignore:
Features
🌏 A Note on Multilingual Support
This extension supports all 17 languages that VS Code supports. Additionally, for README documentation, we're challenging ourselves to translate into minority languages and even joke languages. This isn't just "global support" - it's "respect for linguistic diversity." And I'd be happy if this becomes infrastructure where commits that make the world better come from developers living everywhere, transcending language barriers. Quick StartA typical setup for managing personal and work (Enterprise Managed User) accounts. Step 1: Prepare SSH KeysFirst, create SSH keys for each account (skip if you already have them):
Register the public key (
Step 2: Configure SSHEdit
Step 3: Configure the ExtensionOpen extension settings (
Step 4: Use It
Using SSH Host AliasesWhen cloning repos, use the host that corresponds to your identity:
Optional: GPG SigningIf you sign commits with GPG: Step 1: Find Your GPG Key ID
Output example:
The key ID is Step 2: Add GPG Key to Identity
When you switch to this identity, the extension sets:
Full Example: 4 Accounts with SSH + GPGHere's a complete example combining everything: SSH Config (
|
| Property | Required | Description |
|---|---|---|
id |
✅ | Unique identifier (e.g., "work", "personal") |
name |
✅ | Git user.name - shown in commits |
email |
✅ | Git user.email - shown in commits |
icon |
Emoji shown in status bar (e.g., "🏠"). Single emoji only |
|
service |
Service name (e.g., "GitHub", "GitLab"). Used for UI display |
|
description |
Short description shown in picker and tooltip | |
sshKeyPath |
Path to SSH private key (e.g., "~/.ssh/id_ed25519_work") |
|
sshHost |
SSH config Host alias (e.g., "github-work") |
|
gpgKeyId |
GPG key ID for commit signing |
Display Limitations
- Status bar: Text exceeding ~25 characters will be truncated with
... icon: Only a single emoji (grapheme cluster) is allowed. Multiple emojis or long strings are not supported
Global Settings
| Setting | Default | Description |
|---|---|---|
gitIdSwitcher.identities |
See sample | List of identity configurations |
gitIdSwitcher.defaultIdentity |
See sample | ID of default identity to use |
gitIdSwitcher.autoSwitchSshKey |
true |
Auto-switch SSH key when changing identities |
gitIdSwitcher.showNotifications |
true |
Show notification on identity switch |
gitIdSwitcher.applyToSubmodules |
true |
Propagate identity to Git submodules |
gitIdSwitcher.submoduleDepth |
1 |
Max depth for nested submodule config (1-5) |
gitIdSwitcher.includeIconInGitConfig |
false |
Include icon emoji in Git config user.name |
gitIdSwitcher.logging.fileEnabled |
false |
Enable audit logging (identity switches, SSH operations) |
gitIdSwitcher.logging.filePath |
"" |
Log file path (e.g., ~/.git-id-switcher/security.log). Empty = default location |
gitIdSwitcher.logging.maxFileSize |
10485760 |
Max file size before rotation (bytes, 1MB-100MB) |
gitIdSwitcher.logging.maxFiles |
5 |
Max rotated log files to keep (1-20) |
gitIdSwitcher.logging.level |
"INFO" |
Log level: DEBUG/INFO/WARN/ERROR/SECURITY. Records selected level and above |
gitIdSwitcher.logging.redactAllSensitive |
false |
When enabled, all values are masked in logs (maximum privacy mode) |
gitIdSwitcher.commandTimeouts |
{} |
Custom timeout per command (ms, 1sec-5min). E.g., {"git": 15000, "ssh-add": 10000} |
About includeIconInGitConfig
Controls behavior when icon field is set:
| Value | Behavior |
|---|---|
false (default) |
icon is shown in editor UI only. Only name is written to Git config |
true |
icon + name is written to Git config. Emoji appears in commit history |
Example: icon: "👤", name: "Alex Smith"
| includeIconInGitConfig | Git config user.name |
Commit signature |
|---|---|---|
false |
Alex Smith |
Alex Smith <email> |
true |
👤 Alex Smith |
👤 Alex Smith <email> |
Note: Basic Setup (No SSH)
If you don't need SSH key switching (e.g., using different committer info with a single GitHub account), you can use a minimal configuration:
{
"gitIdSwitcher.identities": [
{
"id": "personal",
"icon": "🏠",
"name": "Alex Smith",
"email": "alex@personal.example.com",
"description": "Personal projects"
},
{
"id": "work",
"icon": "💼",
"name": "Alex Smith",
"email": "alex.smith@company.example.com",
"description": "Work account"
}
]
}
This setup only switches git config user.name and user.email.
How It Works
Git Config Layer Structure
Git configuration has three layers, where lower layers override higher ones:
System (/etc/gitconfig)
↓ overrides
Global (~/.gitconfig)
↓ overrides
Local (.git/config) ← highest priority
Git ID Switcher writes to --local (repository-local).
This means:
- Identity is saved to each repository's
.git/config - Different identities can be maintained per repository
- Global settings (
~/.gitconfig) are not modified
When Switching Identities
When you switch identities, the extension does (in order):
- Git Config (always): Sets
git config --local user.nameanduser.email - SSH Key (if
sshKeyPathset): Removes other keys from ssh-agent, adds the selected one - GPG Key (if
gpgKeyIdset): Setsgit config --local user.signingkeyand enables signing - Submodules (if enabled): Propagates config to all submodules (default: depth 1)
How Submodule Propagation Works
Local settings are per-repository, so they don't automatically apply to submodules. That's why this extension provides submodule propagation (see "Advanced: Submodule Support" for details).
SSH Key Management Details
Git ID Switcher manages SSH keys through ssh-agent:
| Operation | Command |
|---|---|
| Add key | ssh-add <keyPath> |
| Remove key | ssh-add -d <keyPath> |
| List keys | ssh-add -l |
Important: This extension does NOT modify ~/.ssh/config. You need to set up your SSH config manually (see Step 2 in "Quick Start").
Interaction with Existing SSH Config
If you already have SSH configuration, Git ID Switcher works alongside it:
| Your Setup | Git ID Switcher Behavior |
|---|---|
~/.ssh/config with IdentityFile |
Both can be used; use IdentitiesOnly yes to prevent conflicts |
GIT_SSH_COMMAND environment variable |
Git uses your custom SSH command; ssh-agent still works |
git config core.sshCommand |
Same as above |
| direnv with SSH-related env vars | Works alongside; ssh-agent operates independently |
Recommended: Always use IdentitiesOnly yes in your SSH config. This prevents SSH from trying multiple keys.
Why IdentitiesOnly yes?
Without this setting, SSH may try keys in this order:
- Keys loaded in ssh-agent (managed by Git ID Switcher)
- Keys specified in
~/.ssh/config - Default keys (
~/.ssh/id_rsa,~/.ssh/id_ed25519, etc.)
This can cause authentication failures or unintended key usage.
With IdentitiesOnly yes, SSH uses only the specified key. This ensures the key you configured in Git ID Switcher is used reliably.
# Recommended configuration
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes # ← This line is important
With this configuration, connections to the github-work host will only use ~/.ssh/id_ed25519_work, and no other keys will be tried.
Advanced: Submodule Support
For complex repositories using Git Submodules, identity management is often a pain. If you commit in a submodule, Git uses the local config of that submodule, which might default to your global config (wrong email!) if not explicitly set.
Git ID Switcher automatically detects submodules and applies the selected identity to them.
{
"gitIdSwitcher.applyToSubmodules": true,
"gitIdSwitcher.submoduleDepth": 1
}
applyToSubmodules: Enable/disable this featuresubmoduleDepth: How deep to go?1: Direct submodules only (most common)2+: Nested submodules (submodules within submodules)
This ensures that no matter where you commit—in the main repo or a vendored library—your identity is always correct.
Troubleshooting
SSH key not switching?
Ensure
ssh-agentis running:eval "$(ssh-agent -s)"Check key path is correct:
ls -la ~/.ssh/id_ed25519_*On macOS, add to Keychain once:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
Wrong identity on push?
Check remote URL uses correct host alias:
git remote -v # Should show git@github-work:... for work reposUpdate if needed:
git remote set-url origin git@github-work:company/repo.git
GPG signing not working?
Find your GPG key ID:
gpg --list-secret-keys --keyid-format SHORTTest signing:
echo "test" | gpg --clearsignMake sure the email in your identity matches the GPG key's email.
Identity not detected?
- Make sure you're in a Git repository
- Check
settings.jsonfor syntax errors - Reload VS Code window (
Cmd+Shift+P→ "Reload Window")
Error with name field?
The following characters in the name field will cause an error:
` $ ( ) { } | & < >
Use the service field if you want to include service information.
// NG
"name": "Alex Smith (Personal)"
// OK
"name": "Alex Smith",
"service": "GitHub"
New settings not showing?
After updating the extension, new settings may not appear in the settings UI.
Solution: Restart your machine completely.
VS Code-based editors cache the settings schema in memory, and "Reload Window" or reinstalling the extension may not be enough to refresh it.
Default values empty?
If sample settings don't appear even after a fresh install, Settings Sync may be the cause.
If you previously saved empty settings, they may have synced to the cloud and are overwriting the default values on new installations.
Solution:
- Find the setting in the settings UI
- Click the gear icon → "Reset Setting"
- Sync with Settings Sync (this removes the old settings from the cloud)
Commands
| Command | Description |
|---|---|
Git ID Switcher: Select Identity |
Open the identity picker |
Git ID Switcher: Show Current Identity |
Display current identity info |
Git ID Switcher: Show Documentation |
Show documentation |
Design Philosophy
"Who am I?" — That's the only question this extension answers.
Built on Karesansui Architecture: a simple core (100 lines), surrounded by deliberate quality (90% coverage, logging, timeouts) and intentional constraints (no GitHub API, no token management).
Contributing
Contributions welcome! See CONTRIBUTING.md.
License
MIT License - see LICENSE.
Credits
Created by Null;Variant