惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
J
Java Code Geeks
量子位
腾讯CDC
C
Check Point Blog
小众软件
小众软件
IT之家
IT之家
I
InfoQ
Hugging Face - Blog
Hugging Face - Blog
Stack Overflow Blog
Stack Overflow Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
博客园_首页
S
SegmentFault 最新的问题
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
T
Tailwind CSS Blog
Martin Fowler
Martin Fowler

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Git com múltiplas contas: configure trabalho e pessoal no...
André Moreira · 2026-06-24 · via DEV Community

Você já fez um commit no repositório do trabalho e percebeu que estava com o seu e-mail pessoal? Ou o contrário? Esse é um dos erros mais comuns de quem usa Git com múltiplas contas no mesmo computador.

Neste tutorial você vai aprender a configurar tudo corretamente, de uma vez, usando chaves SSH separadas e .gitconfig condicional — sem gambiarras.


O problema

Por padrão o Git usa uma configuração global:

git config --global user.name "Seu Nome"
git config --global user.email "seu@email.com"

Isso significa que todos os repositórios no seu computador usam o mesmo usuário. Quando você tem contas separadas (ex: joao@empresa.com no GitLab da empresa e joao@gmail.com no GitLab pessoal), os commits vão sair com o e-mail errado.

A solução profissional envolve duas partes:

  1. Chaves SSH separadas para cada conta
  2. .gitconfig condicional que aplica o usuário certo — e a chave SSH certa — por pasta

Passo 1 — Gerar as chaves SSH

Abra o terminal e gere uma chave para cada conta. Use nomes diferentes para não sobrescrever:

# Chave para a conta pessoal
ssh-keygen -t ed25519 -C "joao@gmail.com" -f ~/.ssh/id_ed25519_pessoal

# Chave para a conta do trabalho
ssh-keygen -t ed25519 -C "joao@empresa.com" -f ~/.ssh/id_ed25519_trabalho

💡 Por que ed25519? É o algoritmo mais moderno, mais seguro e recomendado pelo GitHub, GitLab e Bitbucket. Evite RSA a menos que seu servidor seja muito antigo.

Ao final você terá quatro arquivos em ~/.ssh/:

id_ed25519_pessoal      ← chave privada (nunca compartilhe)
id_ed25519_pessoal.pub  ← chave pública (você registra no GitLab)
id_ed25519_trabalho
id_ed25519_trabalho.pub


Passo 2 — Registrar as chaves no GitLab

Para cada conta:

  1. Copie o conteúdo da chave pública:
# Pessoal
cat ~/.ssh/id_ed25519_pessoal.pub

# Trabalho
cat ~/.ssh/id_ed25519_trabalho.pub

  1. Acesse Settings → SSH and GPG keys → New SSH key na conta correspondente e cole o conteúdo.

Faça isso nas duas contas, cada uma com a sua respectiva chave pública.


Passo 3 — Configurar o Git por pasta (o pulo do gato)

Aqui está o diferencial: usar o includeIf do Git para aplicar configurações diferentes dependendo de onde o repositório está — incluindo qual chave SSH usar, sem precisar mexer no ~/.ssh/config.

A ideia é simples: você organiza seus projetos em pastas separadas:

~/
├── projetos/
│   ├── pessoal/       ← projetos pessoais
│   └── trabalho/      ← projetos da empresa

3.1 — Criar os .gitconfig específicos

Cada arquivo define o usuário e a chave SSH que o Git deve usar naquela pasta. O core.sshCommand instrui o Git a chamar o SSH com uma chave específica e ignorar qualquer configuração do ~/.ssh/config (o -F /dev/null garante isso):

# Configuração pessoal
cat > ~/.gitconfig-pessoal << 'EOF'
[user]
    name = João Silva
    email = joao@gmail.com
[core]
    sshCommand = ssh -i ~/.ssh/id_ed25519_pessoal -F /dev/null
EOF

# Configuração do trabalho
cat > ~/.gitconfig-trabalho << 'EOF'
[user]
    name = João Silva
    email = joao@empresa.com
[core]
    sshCommand = ssh -i ~/.ssh/id_ed25519_trabalho -F /dev/null
EOF

💡 O que é -F /dev/null? Diz ao SSH para ignorar completamente o ~/.ssh/config. Isso evita que configurações globais de SSH interfiram e garante que a chave especificada em -i seja a única usada. Sem essa flag, o SSH ainda pode carregar outras identidades do seu agente.

3.2 — Configurar o .gitconfig global com includeIf

Edite ~/.gitconfig:

vim ~/.gitconfig

Deixe assim:

[user]
    name = João Silva
    email = joao@gmail.com   # fallback (usado fora das pastas mapeadas)

[includeIf "gitdir:~/projetos/pessoal/"]
    path = ~/.gitconfig-pessoal

[includeIf "gitdir:~/projetos/trabalho/"]
    path = ~/.gitconfig-trabalho

⚠️ A barra no final do caminho é obrigatória. ~/projetos/trabalho/ funciona; ~/projetos/trabalho não.


Passo 4 — Testar a conexão SSH

Com os .gitconfig configurados, o teste correto é deixar o Git invocar o SSH automaticamente — sem passar a chave no comando.

O detalhe importante: o includeIf só é ativado dentro de um repositório git. Por isso o teste cria um repo temporário dentro de cada pasta mapeada e roda git ls-remote, que faz uma conexão SSH real sem precisar de nenhum clone:

# Crie as pastas base se ainda não existirem
mkdir -p ~/projetos/pessoal ~/projetos/trabalho

# Teste da conta pessoal
cd ~/projetos/pessoal
git init .teste-pessoal && cd .teste-pessoal
git ls-remote git@gitlab.com:joao-pessoal/meu-projeto.git HEAD
# deve listar o HEAD autenticado como joao-pessoal
cd .. && rm -rf .teste-pessoal

# Teste da conta do trabalho
cd ~/projetos/trabalho
git init .teste-trabalho && cd .teste-trabalho
git ls-remote git@gitlab.com:empresa/projeto-empresa.git HEAD
# deve listar o HEAD autenticado como conta da empresa
cd .. && rm -rf .teste-trabalho

💡 O git init dentro da pasta é necessário porque o includeIf "gitdir:..." só é avaliado quando o Git está operando dentro de um repositório. O ls-remote faz a conexão SSH sem precisar de histórico ou commits — é o teste mais leve possível.

Se aparecer Permission denied (publickey), volte ao Passo 2 e verifique se a chave pública foi cadastrada na conta correta.


Passo 5 — Clonar repositórios

Com essa abordagem, as URLs de clone continuam normais — você usa git@gitlab.com em todos os casos. O Git saberá qual chave usar com base na pasta onde o repositório está:

# Repositório pessoal — clone normalmente dentro de ~/projetos/pessoal/
git clone git@gitlab.com:joao-pessoal/meu-projeto.git ~/projetos/pessoal/meu-projeto

# Repositório do trabalho — clone dentro de ~/projetos/trabalho/
git clone git@gitlab.com:empresa/projeto-empresa.git ~/projetos/trabalho/projeto-empresa

Para repositórios já clonados fora da pasta certa, mova-os para a pasta correta ou defina o sshCommand manualmente só naquele repo:

cd ~/algum-repo-avulso
git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_trabalho -F /dev/null"
git config user.email "joao@empresa.com"


Verificação final

Dentro de cada repositório, confirme que o Git está usando o usuário e a chave corretos:

cd ~/projetos/trabalho/projeto-empresa
git config user.email
# deve retornar: joao@empresa.com

git config core.sshCommand
# deve retornar: ssh -i ~/.ssh/id_ed25519_trabalho -F /dev/null

cd ~/projetos/pessoal/meu-projeto
git config user.email
# deve retornar: joao@gmail.com


Resumo da estrutura

~/.ssh/
├── id_ed25519_pessoal        ← chave privada pessoal
├── id_ed25519_pessoal.pub
├── id_ed25519_trabalho       ← chave privada do trabalho
└── id_ed25519_trabalho.pub

~/.gitconfig                  ← config global com includeIf
~/.gitconfig-pessoal          ← user, email e sshCommand pessoal
~/.gitconfig-trabalho         ← user, email e sshCommand do trabalho

~/projetos/
├── pessoal/                  ← clones pessoais aqui
└── trabalho/                 ← clones do trabalho aqui


Problemas comuns

"Still using the wrong email after setup"
Verifique se a barra final está no includeIf. Rode git config user.email dentro do repositório (não globalmente).

"Permission denied (publickey)"
Rode ssh -i ~/.ssh/id_ed25519_trabalho -vT git@gitlab.com para ver o que acontece. Confirme que a chave pública está cadastrada na conta correta no GitLab.

"sshCommand não está sendo aplicado"
Confirme que o repositório está dentro da pasta mapeada no includeIf e que a barra final está presente. Teste com git config core.sshCommand dentro do repo.


Conclusão

Com essa configuração você nunca mais vai:

  • ❌ Commitar com o e-mail errado
  • ❌ Misturar credenciais de contas diferentes
  • ❌ Precisar criar aliases de host no ~/.ssh/config
  • ❌ Precisar configurar manualmente cada repositório

A lógica é elegante: o includeIf do Git ativa automaticamente o user, o email e o core.sshCommand certos com base na pasta — tudo em um único lugar, sem efeitos colaterais no restante do sistema.


Gostou? Deixa uma reação e compartilha com aquele dev que sempre commita com o e-mail errado 👇