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:
- Professional embarrassment when personal commits show up in corporate repositories
- Privacy concerns when work email addresses leak into personal projects
- Compliance issues in regulated industries
- Confusion when trying to track contributions across different contexts
- Broken workflows when company policies require specific email domains
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:
- Organize your projects into logical directory structures
- Use conditional includes for automatic profile switching
- Implement validation through hooks and scripts
- Test your setup regularly to ensure it’s working correctly
- Document your configuration for future reference
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!