Skip to content
$ gitswitch
Nord
★ star

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:

For each client, generate a unique SSH key:

Terminal window
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"

For each client (GitHub, GitLab, Bitbucket, etc.):

  1. Get public key: cat ~/.ssh/id_clienta.pub
  2. Add to their service’s SSH keys section
  3. Test: ssh -T git@github.com (should work with that key)
Terminal window
# Client A
gitswitch add clienta "Your Name" you@clienta.com \
--ssh-key ~/.ssh/id_clienta
# Client B
gitswitch add clientb "Your Name" you@clientb.com \
--ssh-key ~/.ssh/id_clientb
# Personal projects
gitswitch add personal "Your Name" you@personal.com \
--ssh-key ~/.ssh/id_personal
Terminal window
cd ~/clienta-project
gitswitch clienta
# Now all commits are attributed to you@clienta.com using id_clienta
cd ~/clientb-project
gitswitch clientb
# Switch to client B identity

If you’ve run gitswitch install, you get automatic nudges:

Terminal window
cd ~/clienta-project
# gitswitch: this repo usually uses clienta — switch? [y/N]
# Press 'y' to switch automatically

Pin each repo for permanent association:

Terminal window
cd ~/clienta-project
gitswitch pin clienta
cd ~/clientb-project
gitswitch pin clientb
# Now nudges become persistent — you'll always be suggested the right identity

If you clone the same client repo in multiple locations:

Terminal window
# Location 1 - working copy
cd ~/projects/clienta-main
gitswitch pin clienta
# Location 2 - backup
cd ~/backup/clienta-archive
gitswitch pin clienta
# Each location learns/respects the pin independently
Terminal window
# Finish client A work
cd ~/clienta-project
# Verify active identity
gitswitch current
# → clienta / you@clienta.com
# Switch to client B
gitswitch clientb
# Check identity updated
gitswitch current
# → clientb / you@clientb.com
# Now make commits - they use clientb identity and SSH key
git commit -m "Fix bug for client B"

Always verify before pushing to a client repo:

Terminal window
# Check git config
git config --global user.email
# Should show client email
# Test SSH with client's service
ssh -T git@github.com # or their GitLab/Bitbucket
# Should show you're authenticated as that client
# Check git log to see recent commits' authors
git log -1 --format="%an <%ae>"
# Should show your name and client email

If you committed with the wrong identity before pushing:

Terminal window
# Don't push yet! Amend the commit
gitswitch clienta # Switch to right identity
git commit --amend --reset-author
git push

Once pushed, the attribution is permanent.

If you get Permission denied (publickey):

Terminal window
# Verify SSH is using the right key
gitswitch current
# Should show the right profile
# Test SSH directly
ssh -i ~/.ssh/id_clienta -T git@github.com
# Should authenticate as client A
# If that works, check git can use the key
git config --global core.sshCommand
# Should show: ssh -i ~/.ssh/id_clienta -o IdentitiesOnly=yes

Check shell history or repo remotes:

Terminal window
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 recently

Add to ~/.zshrc or ~/.bashrc:

Terminal window
alias gs='gitswitch'
alias gsc='gitswitch current'
alias gsl='gitswitch list'

Now:

Terminal window
gs clienta # Quick switch
gsc # Check current identity
gsl # List all profiles
Terminal window
~/clients/
├── clienta/
├── main-repo/
├── staging-repo/
└── ...
├── clientb/
├── project-x/
├── project-y/
└── ...
└── personal/
├── github-projects/
└── ...

Pin each top-level directory:

Terminal window
cd ~/clients/clienta/main-repo
gitswitch pin clienta
# All clienta projects now nudge to clienta identity

If a client needs specific git hooks or signing:

Terminal window
cd ~/clienta-project
# Set repo-specific GPG key (overrides global)
git config --local user.signingkey CLIENTA_GPG_KEY_ID
# Set repo-specific sign config
git config --local commit.gpgsign true
# Verify
git config --local --list

If your identity reverts:

  1. Check for Git hooks in the repo that modify config
  2. Verify no other tools are changing git config
  3. Look at shell rc files for conflicting aliases
Terminal window
# Check for hooks
ls -la .git/hooks/

You can’t use the same SSH key for multiple profiles:

Terminal window
# Bad - same key used twice
gitswitch add clienta "..." you@a.com --ssh-key ~/.ssh/id_work
gitswitch add clientb "..." you@b.com --ssh-key ~/.ssh/id_work
# Good - unique key per profile
gitswitch add clienta "..." you@a.com --ssh-key ~/.ssh/id_clienta
gitswitch add clientb "..." you@b.com --ssh-key ~/.ssh/id_clientb

If you have 10+ clients, consider:

  1. Grouping — Use profile nicknames like a-main, a-staging, b-dev
  2. Script — Create a shell function that switches based on directory
  3. 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 $CLIENT
fi

Open Source + Work
Multi-account GitHub
CLI Reference