Multi-client Freelancer
This guide covers managing multiple client git identities when freelancing.
You have 3 clients, each with their own git repos and SSH keys:
1. Generate SSH keys
Section titled “1. Generate SSH keys”For each client, generate a unique SSH key:
ssh-keygen -t ed25519 -f ~/.ssh/id_clienta -C "you@clienta.com"ssh-keygen -t ed25519 -f ~/.ssh/id_clientb -C "you@clientb.com"ssh-keygen -t ed25519 -f ~/.ssh/id_personal -C "you@personal.com"2. Add to client git services
Section titled “2. Add to client git services”For each client (GitHub, GitLab, Bitbucket, etc.):
- Get public key:
cat ~/.ssh/id_clienta.pub - Add to their service’s SSH keys section
- Test:
ssh -T git@github.com(should work with that key)
3. Create gitswitch profiles
Section titled “3. Create gitswitch profiles”# Client Agitswitch add clienta "Your Name" you@clienta.com \ --ssh-key ~/.ssh/id_clienta
# Client Bgitswitch add clientb "Your Name" you@clientb.com \ --ssh-key ~/.ssh/id_clientb
# Personal projectsgitswitch add personal "Your Name" you@personal.com \ --ssh-key ~/.ssh/id_personalDaily workflow
Section titled “Daily workflow”Before starting work
Section titled “Before starting work”cd ~/clienta-projectgitswitch clienta# Now all commits are attributed to you@clienta.com using id_clienta
cd ~/clientb-projectgitswitch clientb# Switch to client B identityWith shell integration
Section titled “With shell integration”If you’ve run gitswitch install, you get automatic nudges:
cd ~/clienta-project# gitswitch: this repo usually uses clienta — switch? [y/N]# Press 'y' to switch automaticallyPin each repo for permanent association:
cd ~/clienta-projectgitswitch pin clienta
cd ~/clientb-projectgitswitch pin clientb
# Now nudges become persistent — you'll always be suggested the right identityManaging multiple repos per client
Section titled “Managing multiple repos per client”If you clone the same client repo in multiple locations:
# Location 1 - working copycd ~/projects/clienta-maingitswitch pin clienta
# Location 2 - backupcd ~/backup/clienta-archivegitswitch pin clienta
# Each location learns/respects the pin independentlySwitching between clients
Section titled “Switching between clients”# Finish client A workcd ~/clienta-project
# Verify active identitygitswitch current# → clienta / you@clienta.com
# Switch to client Bgitswitch clientb
# Check identity updatedgitswitch current# → clientb / you@clientb.com
# Now make commits - they use clientb identity and SSH keygit commit -m "Fix bug for client B"Verifying correct identity before pushing
Section titled “Verifying correct identity before pushing”Always verify before pushing to a client repo:
# Check git configgit config --global user.email# Should show client email
# Test SSH with client's servicessh -T git@github.com # or their GitLab/Bitbucket# Should show you're authenticated as that client
# Check git log to see recent commits' authorsgit log -1 --format="%an <%ae>"# Should show your name and client emailCommon mistakes
Section titled “Common mistakes”Wrong identity on committed code
Section titled “Wrong identity on committed code”If you committed with the wrong identity before pushing:
# Don't push yet! Amend the commitgitswitch clienta # Switch to right identity
git commit --amend --reset-author
git pushOnce pushed, the attribution is permanent.
SSH key rejected
Section titled “SSH key rejected”If you get Permission denied (publickey):
# Verify SSH is using the right keygitswitch current# Should show the right profile
# Test SSH directlyssh -i ~/.ssh/id_clienta -T git@github.com# Should authenticate as client A
# If that works, check git can use the keygit config --global core.sshCommand# Should show: ssh -i ~/.ssh/id_clienta -o IdentitiesOnly=yesForgot which client owns a repo
Section titled “Forgot which client owns a repo”Check shell history or repo remotes:
git remote -v# Shows the URL, which should indicate the client
# Or check recent commits:git log -3 --format="%an <%ae>"# Shows which identities were used recentlyStreamlining workflow
Section titled “Streamlining workflow”Alias for quick switches
Section titled “Alias for quick switches”Add to ~/.zshrc or ~/.bashrc:
alias gs='gitswitch'alias gsc='gitswitch current'alias gsl='gitswitch list'Now:
gs clienta # Quick switchgsc # Check current identitygsl # List all profilesOrganization with per-client directories
Section titled “Organization with per-client directories”~/clients/├── clienta/│ ├── main-repo/│ ├── staging-repo/│ └── ...├── clientb/│ ├── project-x/│ ├── project-y/│ └── ...└── personal/ ├── github-projects/ └── ...Pin each top-level directory:
cd ~/clients/clienta/main-repogitswitch pin clienta# All clienta projects now nudge to clienta identityAdvanced: Per-repo secrets
Section titled “Advanced: Per-repo secrets”If a client needs specific git hooks or signing:
cd ~/clienta-project
# Set repo-specific GPG key (overrides global)git config --local user.signingkey CLIENTA_GPG_KEY_ID
# Set repo-specific sign configgit config --local commit.gpgsign true
# Verifygit config --local --listTroubleshooting
Section titled “Troubleshooting”Identity keeps switching back
Section titled “Identity keeps switching back”If your identity reverts:
- Check for Git hooks in the repo that modify config
- Verify no other tools are changing git config
- Look at shell rc files for conflicting aliases
# Check for hooksls -la .git/hooks/SSH key in use by another profile
Section titled “SSH key in use by another profile”You can’t use the same SSH key for multiple profiles:
# Bad - same key used twicegitswitch add clienta "..." you@a.com --ssh-key ~/.ssh/id_workgitswitch add clientb "..." you@b.com --ssh-key ~/.ssh/id_work
# Good - unique key per profilegitswitch add clienta "..." you@a.com --ssh-key ~/.ssh/id_clientagitswitch add clientb "..." you@b.com --ssh-key ~/.ssh/id_clientbToo many profiles to manage
Section titled “Too many profiles to manage”If you have 10+ clients, consider:
- Grouping — Use profile nicknames like
a-main,a-staging,b-dev - Script — Create a shell function that switches based on directory
- Dynamic — Write a wrapper script that auto-detects client from git remote
Example wrapper:
#!/bin/bash# In ~/.local/bin/smart-gitswitch
CLIENT=$(git config --get remote.origin.url | grep -oE 'clienta|clientb')if [ -n "$CLIENT" ]; then gitswitch $CLIENTfi