How to Setup Multiple Git Accounts on macOS

Cover Image for How to Setup Multiple Git Accounts on macOS
DevOps5 min read

Managing multiple Git accounts on macOS can be challenging, especially when you need to switch between personal, work, and client repositories. This guide will walk you through setting up multiple Git accounts with proper SSH key management and automatic account switching.

Why You Need Multiple Git Accounts

Common scenarios include:

  • Personal projects using your personal GitHub account
  • Work repositories using your company's GitLab/GitHub Enterprise account
  • Client projects using separate accounts for different clients
  • Open source contributions using a dedicated account

Prerequisites

  • macOS (any recent version)
  • Git installed (git --version to check)
  • SSH client (included with macOS)
  • Access to your Git hosting services (GitHub, GitLab, etc.)

Step 1: Generate SSH Keys for Each Account

Create SSH Keys

Generate a unique SSH key for each account:

# Personal account (GitHub)
ssh-keygen -t ed25519 -C "your-personal-email@example.com" -f ~/.ssh/id_ed25519_personal

# Work account
ssh-keygen -t ed25519 -C "your-work-email@company.com" -f ~/.ssh/id_ed25519_work

# Client account
ssh-keygen -t ed25519 -C "your-client-email@client.com" -f ~/.ssh/id_ed25519_client

Add Keys to SSH Agent

# Start SSH agent
eval "$(ssh-agent -s)"

# Add each key
ssh-add ~/.ssh/id_ed25519_personal
ssh-add ~/.ssh/id_ed25519_work
ssh-add ~/.ssh/id_ed25519_client

# Verify keys are loaded
ssh-add -l

Step 2: Configure SSH Config

Create or edit ~/.ssh/config to define host aliases:

nano ~/.ssh/config

Add the following configuration:

# Personal GitHub account
Host github.com-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

# Work GitHub account
Host github.com-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

# Client GitHub account
Host github.com-client
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_client
    IdentitiesOnly yes

# GitLab work account
Host gitlab.com-work
    HostName gitlab.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Step 3: Add SSH Keys to Git Hosting Services

For GitHub

  1. Copy your public key:

    # Personal
    cat ~/.ssh/id_ed25519_personal.pub | pbcopy
    
    # Work
    cat ~/.ssh/id_ed25519_work.pub | pbcopy
    
    # Client
    cat ~/.ssh/id_ed25519_client.pub | pbcopy
    
  2. Go to GitHub → Settings → SSH and GPG keys → New SSH key

  3. Paste each key with a descriptive title (e.g., "MacBook Pro - Personal", "MacBook Pro - Work")

For GitLab

  1. Go to GitLab → Preferences → SSH Keys
  2. Add each public key with appropriate titles

Step 4: Test SSH Connections

Test each connection:

# Test personal account
ssh -T github.com-personal

# Test work account
ssh -T github.com-work

# Test client account
ssh -T github.com-client

# Test GitLab work account
ssh -T gitlab.com-work

You should see success messages like:

Hi username! You've successfully authenticated, but GitHub does not provide shell access.

Step 5: Configure Git with Conditional Includes

Create Git Config Files

Create separate config files for each account:

# Personal config
nano ~/.gitconfig_personal
[user]
    name = Your Personal Name
    email = your-personal-email@example.com

[core]
    sshCommand = ssh -i ~/.ssh/id_ed25519_personal -F /dev/null

[url "git@github.com-personal:"]
    insteadOf = git@github.com:
# Work config
nano ~/.gitconfig_work
[user]
    name = Your Work Name
    email = your-work-email@company.com

[core]
    sshCommand = ssh -i ~/.ssh/id_ed25519_work -F /dev/null

[url "git@github.com-work:"]
    insteadOf = git@github.com:

[url "git@gitlab.com-work:"]
    insteadOf = git@gitlab.com:
# Client config
nano ~/.gitconfig_client
[user]
    name = Your Client Name
    email = your-client-email@client.com

[core]
    sshCommand = ssh -i ~/.ssh/id_ed25519_client -F /dev/null

[url "git@github.com-client:"]
    insteadOf = git@github.com:

Configure Main Git Config

Edit your main ~/.gitconfig:

nano ~/.gitconfig
[includeIf "gitdir:~/personal/"]
    path = ~/.gitconfig_personal

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig_work

[includeIf "gitdir:~/clients/"]
    path = ~/.gitconfig_client

# Default fallback
[user]
    name = Your Default Name
    email = your-default-email@example.com

Step 6: Organize Your Repository Structure

Create organized directories for different accounts:

# Create directory structure
mkdir -p ~/personal
mkdir -p ~/work
mkdir -p ~/clients

# Clone repositories into appropriate directories
cd ~/personal
git clone git@github.com-personal:username/personal-project.git

cd ~/work
git clone git@github.com-work:company/work-project.git

cd ~/clients
git clone git@github.com-client:client/client-project.git

Step 7: Create Helper Scripts

Git Account Switcher Script

Create a script to easily switch between accounts:

nano ~/bin/git-switch-account
#!/bin/bash

# Git Account Switcher
# Usage: git-switch-account [personal|work|client]

case $1 in
    personal)
        git config --global user.name "Your Personal Name"
        git config --global user.email "your-personal-email@example.com"
        git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519_personal -F /dev/null"
        echo "Switched to personal account"
        ;;
    work)
        git config --global user.name "Your Work Name"
        git config --global user.email "your-work-email@company.com"
        git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519_work -F /dev/null"
        echo "Switched to work account"
        ;;
    client)
        git config --global user.name "Your Client Name"
        git config --global user.email "your-client-email@client.com"
        git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519_client -F /dev/null"
        echo "Switched to client account"
        ;;
    *)
        echo "Usage: git-switch-account [personal|work|client]"
        echo "Current configuration:"
        git config --global user.name
        git config --global user.email
        ;;
esac

Make it executable:

chmod +x ~/bin/git-switch-account

Repository Cloning Helper

Create a script to clone repositories with the correct account:

nano ~/bin/git-clone-account
#!/bin/bash

# Git Clone with Account
# Usage: git-clone-account [personal|work|client] <repository-url>

if [ $# -ne 2 ]; then
    echo "Usage: git-clone-account [personal|work|client] <repository-url>"
    exit 1
fi

ACCOUNT=$1
REPO_URL=$2

case $ACCOUNT in
    personal)
        # Replace github.com with github.com-personal
        MODIFIED_URL=$(echo $REPO_URL | sed 's/github\.com/github.com-personal/g')
        git clone $MODIFIED_URL
        ;;
    work)
        # Replace github.com with github.com-work
        MODIFIED_URL=$(echo $REPO_URL | sed 's/github\.com/github.com-work/g')
        git clone $MODIFIED_URL
        ;;
    client)
        # Replace github.com with github.com-client
        MODIFIED_URL=$(echo $REPO_URL | sed 's/github\.com/github.com-client/g')
        git clone $MODIFIED_URL
        ;;
    *)
        echo "Invalid account. Use: personal, work, or client"
        exit 1
        ;;
esac

Make it executable:

chmod +x ~/bin/git-clone-account

Step 8: Usage Examples

Cloning Repositories

# Clone personal repository
git-clone-account personal git@github.com:username/personal-project.git

# Clone work repository
git-clone-account work git@github.com:company/work-project.git

# Clone client repository
git-clone-account client git@github.com:client/client-project.git

Switching Accounts Globally

# Switch to personal account
git-switch-account personal

# Switch to work account
git-switch-account work

# Check current configuration
git-switch-account

Working with Existing Repositories

For existing repositories, you can change the remote URL:

# Change to use personal account
git remote set-url origin git@github.com-personal:username/repo.git

# Change to use work account
git remote set-url origin git@github.com-work:company/repo.git

Step 9: Troubleshooting

Common Issues

  1. SSH Key Not Found

    # Check if keys are loaded
    ssh-add -l
    
    # Re-add keys if needed
    ssh-add ~/.ssh/id_ed25519_personal
    
  2. Permission Denied

    # Test SSH connection
    ssh -T github.com-personal
    
    # Check SSH config
    cat ~/.ssh/config
    
  3. Wrong Account Used

    # Check current Git config
    git config --list | grep user
    
    # Check remote URL
    git remote -v
    
  4. SSH Agent Not Running

    # Start SSH agent
    eval "$(ssh-agent -s)"
    
    # Add keys
    ssh-add ~/.ssh/id_ed25519_personal
    

Debugging Commands

# Test SSH connection with verbose output
ssh -vT github.com-personal

# Check Git configuration
git config --list --show-origin

# Check SSH configuration
ssh -F ~/.ssh/config -T github.com-personal

Step 10: Best Practices

Security

  1. Use strong passphrases for your SSH keys
  2. Regularly rotate SSH keys (every 6-12 months)
  3. Use different keys for different environments
  4. Never share private keys

Organization

  1. Use consistent directory structure for different accounts
  2. Name SSH keys descriptively (e.g., id_ed25519_personal_macbook)
  3. Document your setup for team members
  4. Use Git hooks for additional automation

Maintenance

  1. Regularly update SSH keys on hosting services
  2. Test connections after system updates
  3. Backup SSH keys securely
  4. Monitor for security alerts from hosting services

Advanced Configuration

Using Git Hooks

Create a pre-commit hook to verify the correct account:

nano ~/.git-templates/hooks/pre-commit
#!/bin/bash

# Check if we're in the right directory for the account
CURRENT_DIR=$(pwd)
EXPECTED_EMAIL=""

if [[ $CURRENT_DIR == *"/personal/"* ]]; then
    EXPECTED_EMAIL="your-personal-email@example.com"
elif [[ $CURRENT_DIR == *"/work/"* ]]; then
    EXPECTED_EMAIL="your-work-email@company.com"
elif [[ $CURRENT_DIR == *"/clients/"* ]]; then
    EXPECTED_EMAIL="your-client-email@client.com"
fi

CURRENT_EMAIL=$(git config user.email)

if [ "$CURRENT_EMAIL" != "$EXPECTED_EMAIL" ]; then
    echo "Warning: Using email '$CURRENT_EMAIL' in directory that expects '$EXPECTED_EMAIL'"
    echo "Consider switching accounts with: git-switch-account [personal|work|client]"
fi

Make it executable:

chmod +x ~/.git-templates/hooks/pre-commit

Additional Resources