Article

Mastering Multiple Git Profiles: The Developer’s Guide to Seamless Identity Management

7 min read
Originally published on Medium. Read, clap or comment on Medium ↗

Stop committing with the wrong email address and take control of your Git identity across all your projects

Picture this: You’re working on a personal side project late at night, making great progress, committing code left and right. The next morning, you check your work repository and realize with horror that your personal email address is now forever embedded in your company’s commit history. Sound familiar?

If you’re a developer juggling multiple identities — personal projects, work repositories, open-source contributions, client work — you’ve likely faced the challenge of managing different Git configurations. The good news? There’s a elegant solution that will save you from this identity crisis forever.

In this comprehensive guide, we’ll explore how to set up and manage multiple Git profiles like a pro, ensuring you never accidentally commit with the wrong identity again.

The Problem: One Size Doesn’t Fit All

Most developers start with a simple global Git configuration:

git config --global user.name "John Doe"
git config --global user.email "john@personal.com"

This works perfectly… until it doesn’t. The moment you start contributing to work projects, open-source repositories, or client codebases, you need different identities for different contexts. Using your personal email for work commits (or vice versa) can lead to:

Solution 1: The Directory-Based Approach (Recommended)

The most elegant solution leverages Git’s conditional includes feature, introduced in Git 2.13. This approach automatically applies different configurations based on the repository location.

Setting Up the Foundation

First, organize your projects into logical directories:

~/Projects/
├── personal/ # Personal projects
├── work/ # Company projects
├── client-a/ # Client A projects
└── opensource/ # Open source contributions

Creating Profile-Specific Configurations

Create separate Git configuration files for each context:

~/.gitconfig-personal

[user]
name = John Doe
email = john@personal.com
signingkey = ABC123DEF456 # Your personal GPG key
[github]
user = johndoe-personal[core]
sshCommand = ssh -i ~/.ssh/id_rsa_personal

~/.gitconfig-work

[user]
name = John Doe
email = john.doe@company.com
signingkey = 789XYZ012ABC # Your work GPG key
[github]
user = johndoe-company[core]
sshCommand = ssh -i ~/.ssh/id_rsa_work

~/.gitconfig-opensource

[user]
name = John Doe
email = john@opensource.dev
signingkey = DEF456GHI789
[github]
user = johndoe-oss

The Magic: Conditional Includes

Now, update your main ~/.gitconfig to conditionally include these profiles:

[user]
name = John Doe
email = john@personal.com # Default fallback
# Personal projects
[includeIf "gitdir:~/Projects/personal/"]
path = ~/.gitconfig-personal# Work projects
[includeIf "gitdir:~/Projects/work/"]
path = ~/.gitconfig-work# Open source projects
[includeIf "gitdir:~/Projects/opensource/"]
path = ~/.gitconfig-opensource# Client work
[includeIf "gitdir:~/Projects/client-a/"]
path = ~/.gitconfig-client-a# Global settings that apply everywhere
[core]
editor = code --wait
autocrlf = input

[init]
defaultBranch = main

[pull]
rebase = true

[push]
default = simple
autoSetupRemote = true

Testing Your Setup

Verify that your configuration works correctly:

# In a personal project
cd ~/Projects/personal/my-blog
git config user.email
# Should output: john@personal.com
# In a work project  
cd ~/Projects/work/company-app
git config user.email
# Should output: john.doe@company.com

Solution 2: The Manual Switching Approach

If you prefer more explicit control or can’t organize your projects by directory, you can create utility scripts to switch profiles manually.

Creating Profile Scripts

Create executable scripts for each profile:

~/bin/git-personal

#!/bin/bash
git config user.name "John Doe"
git config user.email "john@personal.com"
git config user.signingkey "ABC123DEF456"
echo "Switched to personal Git profile"

~/bin/git-work

#!/bin/bash
git config user.name "John Doe"
git config user.email "john.doe@company.com"
git config user.signingkey "789XYZ012ABC"
echo "Switched to work Git profile"

Make them executable:

chmod +x ~/bin/git-personal ~/bin/git-work

Add ~/bin to your PATH in your shell profile:

export PATH="$HOME/bin:$PATH"

Advanced: Profile Management with Aliases

Add these handy aliases to your global Git config:

[alias]
# Switch profiles
personal = "!git config user.name 'John Doe' && git config user.email 'john@personal.com'"
work = "!git config user.name 'John Doe' && git config user.email 'john.doe@company.com'"

# Check current profile
whoami = "!echo \"Name: $(git config user.name)\" && echo \"Email: $(git config user.email)\""

# List all profiles (assumes you have profile-specific configs)
profiles = "!grep -E '\\[user\\]|name|email' ~/.gitconfig*"

Usage:

git personal        # Switch to personal profile
git work # Switch to work profile
git whoami # Check current identity

Solution 3: The SSH Key Strategy

For repositories accessed via SSH, you can use different SSH keys for different services and profiles.

Setting Up Multiple SSH Keys

Generate separate SSH keys:

# Personal GitHub
ssh-keygen -t ed25519 -C "john@personal.com" -f ~/.ssh/id_ed25519_personal
# Work GitHub
ssh-keygen -t ed25519 -C "john.doe@company.com" -f ~/.ssh/id_ed25519_work# GitLab
ssh-keygen -t ed25519 -C "john@personal.com" -f ~/.ssh/id_ed25519_gitlab

Configuring SSH

Create or update ~/.ssh/config:

# Personal GitHub
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
# Work GitHub
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes# Personal GitLab
Host gitlab-personal
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab
IdentitiesOnly yes

Using Profile-Specific Remotes

Clone repositories using your custom hosts:

# Personal project
git clone git@github-personal:johndoe/my-project.git
# Work project
git clone git@github-work:company/work-project.git# Change existing remote
git remote set-url origin git@github-personal:johndoe/existing-project.git

Advanced Techniques and Pro Tips

Automatic Profile Detection

Create a script that automatically detects and sets the appropriate profile based on the remote URL:

~/bin/git-auto-profile

#!/bin/bash
REMOTE_URL=$(git config --get remote.origin.url)if [[ $REMOTE_URL == *"@github-work"* ]] || [[ $REMOTE_URL == *"company.github.com"* ]]; then
git config user.email "john.doe@company.com"
echo "Set work profile"
elif [[ $REMOTE_URL == *"@github-personal"* ]] || [[ $REMOTE_URL == *"personal"* ]]; then
git config user.email "john@personal.com"
echo "Set personal profile"
else
echo "Could not determine profile from remote: $REMOTE_URL"
fi

Git Hooks for Profile Validation

Create a pre-commit hook to validate you’re using the correct profile:

.git/hooks/pre-commit

#!/bin/bash
EMAIL=$(git config user.email)
REMOTE_URL=$(git config --get remote.origin.url)# Check if work email is used for personal projects
if [[ $EMAIL == *"@company.com" ]] && [[ $REMOTE_URL == *"personal"* ]]; then
echo "ERROR: Using work email for personal project!"
echo "Current email: $EMAIL"
echo "Remote URL: $REMOTE_URL"
exit 1
fi# Check if personal email is used for work projects
if [[ $EMAIL == *"@personal.com" ]] && [[ $REMOTE_URL == *"company"* ]]; then
echo "ERROR: Using personal email for work project!"
echo "Current email: $EMAIL"
echo "Remote URL: $REMOTE_URL"
exit 1
fi

Shell Integration

Add profile information to your shell prompt:

For Bash (.bashrc):

git_profile() {
if git rev-parse --git-dir > /dev/null 2>&1; then
email=$(git config user.email)
case $email in
*@company.com) echo "[work]" ;;
*@personal.com) echo "[personal]" ;;
*) echo "[git]" ;;
esac
fi
}
PS1='$(git_profile)\u@\h:\w\$ '

Managing GPG Signing Keys

If you sign your commits, configure different GPG keys for different profiles:

# List your GPG keys
gpg --list-secret-keys --keyid-format LONG
# Set signing key in profile config
git config user.signingkey YOUR_KEY_ID
git config commit.gpgsign true

Troubleshooting Common Issues

Problem: Config Not Loading

Symptom: Your conditional includes aren’t working.

Solution: Check your directory paths are correct and use absolute paths:

[includeIf "gitdir:/Users/john/Projects/work/"]  # Absolute path
path = ~/.gitconfig-work

Problem: SSH Authentication Issues

Symptom: “Permission denied” when pushing to repositories.

Solution: Test your SSH connections:

ssh -T git@github-work
ssh -T git@github-personal

Ensure your SSH keys are added to the ssh-agent:

ssh-add ~/.ssh/id_ed25519_work
ssh-add ~/.ssh/id_ed25519_personal

Problem: Wrong Profile in Existing Repository

Symptom: Accidentally committed with wrong email in existing repo.

Solution: Change the config and optionally rewrite history:

# Fix config for future commits
git config user.email "correct@email.com"
# Rewrite last commit (if not pushed)
git commit --amend --reset-author# Rewrite multiple commits (dangerous!)
git rebase -i HEAD~5 --exec "git commit --amend --reset-author --no-edit"

Best Practices and Recommendations

1. Use Directory-Based Organization

Organize your projects into clear directory structures. This makes the conditional includes approach seamless and automatic.

2. Validate Your Setup Regularly

Create a simple script to verify all your profiles are working:

#!/bin/bash
echo "Testing Git profiles..."
for dir in ~/Projects/*/; do
echo "Testing $dir"
cd "$dir"
echo " Email: $(git config user.email)"
echo " Name: $(git config user.name)"
echo ""
done

3. Document Your Setup

Create a README in your home directory documenting your profile setup for future reference.

4. Use Meaningful Commit Messages

Include context about which profile/project type you’re working on if it’s not obvious from the repository.

5. Regular Audits

Periodically review your commit history across platforms to ensure you haven’t leaked identities:

# Check recent commits across all repos
git log --oneline --author="john@personal.com" --all --since="1 month ago"

The Complete Setup Script

Here’s a script to automate the entire setup process:

setup-git-profiles.sh

#!/bin/bash
echo "Setting up Git multiple profiles..."# Create project directories
mkdir -p ~/Projects/{personal,work,opensource,clients}# Backup existing gitconfig
cp ~/.gitconfig ~/.gitconfig.backup# Create profile configs
cat > ~/.gitconfig-personal << EOF
[user]
name = John Doe
email = john@personal.com[core]
sshCommand = ssh -i ~/.ssh/id_ed25519_personal
EOFcat > ~/.gitconfig-work << EOF
[user]
name = John Doe
email = john.doe@company.com[core]
sshCommand = ssh -i ~/.ssh/id_ed25519_work
EOF# Update main gitconfig
cat > ~/.gitconfig << EOF
[user]
name = John Doe
email = john@personal.com[includeIf "gitdir:~/Projects/personal/"]
path = ~/.gitconfig-personal[includeIf "gitdir:~/Projects/work/"]
path = ~/.gitconfig-work[includeIf "gitdir:~/Projects/opensource/"]
path = ~/.gitconfig-personal[core]
editor = code --wait

[init]
defaultBranch = main

[pull]
rebase = true[alias]
whoami = "!echo \"Name: \$(git config user.name)\" && echo \"Email: \$(git config user.email)\""
EOFecho "Git profiles setup complete!"
echo "Edit ~/.gitconfig-* files to customize your profiles."

Conclusion: Identity Management Made Simple

Managing multiple Git profiles doesn’t have to be a source of stress or embarrassment. With the right setup, you can seamlessly switch between different identities while maintaining clean, professional commit histories across all your projects.

The directory-based conditional includes approach is the most elegant solution for most developers, providing automatic profile switching based on project location. Combined with proper SSH key management and validation hooks, you’ll never again worry about committing with the wrong identity.

Key takeaways:

The investment in setting this up properly will pay dividends in professionalism, privacy, and peace of mind. Your future self will thank you for taking the time to get this right.


What’s your approach to managing multiple Git identities? Have you discovered any clever tricks or run into specific challenges? Share your experiences in the comments below!

← All articles Discuss on Medium ↗