Solução de Problemas de Configuração do Git: Correções Comuns e Melhores Práticas

Corrija problemas de configuração do Git rastreando origens das configurações, resolvendo problemas de identidade, alias, hooks, finais de linha, pull e credenciais.

Solução de Problemas de Configuração do Git: Correções Comuns e Melhores Práticas

A maioria dos problemas de configuração do Git parece mais estranha do que realmente é. O Git geralmente está fazendo exatamente o que um de seus arquivos de configuração mandou. A parte difícil é encontrar qual arquivo, porque a configuração pode estar no repositório, na configuração do usuário, na configuração do sistema, em um arquivo incluído ou em uma inclusão condicional que só se aplica em um diretório.

O comando que uso primeiro é este:

git config --list --show-origin --show-scope

Se sua versão do Git não suporta --show-scope, use:

git config --list --show-origin

A origem informa qual arquivo forneceu cada valor. Isso importa mais do que o valor isoladamente. Ver [email protected] não é suficiente; você precisa saber se veio de .git/config, ~/.gitconfig, /etc/gitconfig ou de um perfil de trabalho incluído.

A configuração do Git tem uma ordem de prioridade. A configuração local do repositório normalmente supera a configuração global do usuário, e a configuração global supera a configuração do sistema. Opções de linha de comando e variáveis de ambiente podem substituir todas elas para um comando. Inclusões condicionais adicionam outra camada: um arquivo global pode dizer: "Quando eu estiver dentro deste diretório, carregue esta outra configuração também."

Você pode inspecionar uma configuração com sua origem:

git config --show-origin --get user.email
git config --show-origin --get core.autocrlf
git config --show-origin --get-regexp '^alias\.'

Esse hábito evita muita edição desperdiçada. Se um repositório tem user.email definido localmente, alterar git config --global user.email não afetará os commits naquele repositório.

Nome ou Email Errados nos Commits

O sintoma é simples: os commits mostram o autor errado. Isso geralmente acontece quando você usa o mesmo laptop para projetos pessoais e de trabalho, ou quando clona um repositório da empresa antes de definir seu email de trabalho.

Verifique o que o Git usará no repositório atual:

git config user.name
git config user.email
git config --show-origin --get user.email

Defina sua identidade padrão globalmente:

git config --global user.name "Seu Nome"
git config --global user.email "[email protected]"

Para um repositório, defina localmente:

git config --local user.name "Seu Nome"
git config --local user.email "[email protected]"

Se você quiser que o Git recuse commits quando a identidade não estiver configurada explicitamente, use:

git config --global user.useConfigOnly true

Essa configuração é útil para pessoas que alternam entre identidades. Pode incomodar iniciantes porque o Git vai parar de adivinhar a partir do nome de usuário do sistema e hostname. Use-a quando preferir falhar um commit a criar um com o endereço errado.

Para uma divisão mais limpa entre trabalho e pessoal, use inclusões condicionais:

# ~/.gitconfig
[user]
    name = Seu Nome
    email = [email protected]

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

Depois coloque isso em ~/.gitconfig-trabalho:

[user]
    email = [email protected]

A barra no final em gitdir:~/trabalho/ importa porque significa repositórios dentro daquele diretório. Se não funcionar, execute git config --list --show-origin de dentro de um repositório de trabalho e verifique se o arquivo incluído aparece.

Se você já fez commits com o email errado, alterar a configuração só corrige commits futuros. Para commits não publicados, você pode alterar ou fazer rebase. Para commits já enviados para um branch compartilhado, pergunte antes de reescrever o histórico.

Aliases Que Não Funcionam

Os aliases do Git são armazenados em alias.*. Liste-os assim:

git config --get-regexp '^alias\.'

Um alias normal se expande para um subcomando do Git:

git config --global alias.st 'status -sb'
git st

Se o alias precisar de um pipeline do shell, expansão de variáveis, cd ou outro comando não-Git, deve começar com !:

git config --global alias.recent '!git for-each-ref --sort=-committerdate --count=10 --format="%(refname:short)" refs/heads/'

Sem !, o Git tenta tratar a primeira palavra como um comando Git. ls -la se torna "execute o comando Git chamado ls", que não é o que você queria.

A formatação de citações é a outra falha comum. Se você definir aliases a partir do shell, use aspas simples ao redor de todo o alias quando possível, depois aspas duplas dentro dele conforme necessário. Diferentes shells lidam com citações de forma diferente, especialmente PowerShell e cmd.exe. Se um alias complexo continuar quebrando, edite o arquivo de configuração diretamente:

git config --global --edit

Um truque prático de depuração é começar com o comando fora do Git. Depois que funcionar, cole-o no alias. Se for um alias de shell, prefixe com ! e teste novamente.

Também cuidado com aliases que sombreiam modelos mentais. Um alias chamado pull ou merge pode tornar o comportamento do Git surpreendente. O Git não permite que aliases substituam comandos internos diretamente, mas aliases de shell e scripts wrapper podem. Se git pull se comportar de forma estranha, verifique também sua configuração do shell:

type git
alias | grep git

Hooks Que Nunca Executam

Hooks falham por três razões chatas: o Git está procurando em um diretório de hooks diferente, o arquivo não é executável ou o script assume um ambiente que não possui.

Verifique o caminho de hooks configurado:

git config --show-origin --get core.hooksPath

Se isso imprimir .githooks, o Git usará .githooks/pre-commit, não .git/hooks/pre-commit. Se não imprimir nada, o Git usa .git/hooks.

No macOS e Linux, verifique as permissões:

ls -l .git/hooks/pre-commit .githooks/pre-commit 2>/dev/null
chmod +x .githooks/pre-commit

Um hook que sai com um status diferente de zero bloqueia a operação do Git. Adicione rastreamento temporário perto do topo:

#!/usr/bin/env bash
set -x
pwd
env | sort

Não deixe rastreamento barulhento em um hook compartilhado. Fica ilegível rapidamente.

Problemas de caminho são comuns com clientes GUI. Um hook que funciona no seu terminal pode falhar em um IDE porque o IDE não carregou seu perfil do shell. Prefira comandos locais ao projeto quando possível:

./node_modules/.bin/eslint .

ou verifique o comando e imprima uma mensagem útil:

if ! command -v npm >/dev/null 2>&1; then
  echo "npm é necessário para este hook, mas não foi encontrado no PATH."
  exit 1
fi

Finais de Linha Continuam Mudando

Problemas de final de linha aparecem como arquivos que parecem modificados imediatamente após o checkout, diffs grandes onde cada linha mudou ou scripts que falham no Linux após serem editados no Windows.

Verifique sua configuração:

git config --show-origin --get core.autocrlf
git config --show-origin --get core.eol

Escolhas comuns são:

# Checkout amigável ao Windows, LF no repositório
git config --global core.autocrlf true

# Amigável ao macOS/Linux: converter CRLF para LF apenas no commit
git config --global core.autocrlf input

# Sem conversão automática
git config --global core.autocrlf false

Para uma equipe, .gitattributes é mais confiável do que dizer a cada desenvolvedor para definir globais corretamente. Coloque regras do projeto no repositório:

* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.png binary
*.jpg binary
*.pdf binary

Depois de adicionar ou alterar .gitattributes, normalize os arquivos deliberadamente:

git add --renormalize .
git status

Revise esse diff cuidadosamente. Pode tocar muitos arquivos, e você não quer misturar normalização de final de linha com trabalho de funcionalidade.

Pull, Push ou Merge Usa o Padrão Errado

Às vezes o problema de configuração não é identidade ou finais de linha. É o Git escolhendo uma estratégia de pull que você não esperava.

Verifique as configurações relacionadas ao pull:

git config --show-origin --get pull.rebase
git config --show-origin --get pull.ff
git config --show-origin --get branch.main.rebase

Se git pull continua fazendo rebase quando você esperava um merge, pull.rebase ou uma configuração específica de branch pode estar ativada. Se recusa pulls não-fast-forward, pull.ff=only pode estar definido. Essas configurações não estão erradas por si só; elas só precisam corresponder ao fluxo de trabalho da equipe.

Defina um padrão explícito em vez de viver com avisos e surpresas:

# Merge no pull
git config --global pull.rebase false

# Rebase no pull
git config --global pull.rebase true

# Apenas permitir pulls fast-forward
git config --global pull.ff only

Para um branch:

git config branch.main.rebase true

Confusão com o Credential Helper

Problemas de autenticação muitas vezes parecem problemas remotos, mas vêm da configuração local. O Git pode usar um credential helper que tem um token antigo em cache.

Verifique os helpers:

git config --show-origin --get-all credential.helper

Você pode ver osxkeychain, manager, manager-core, store ou cache. Múltiplos helpers podem existir. Se o Git continua enviando a credencial errada, remova-a do keychain do sistema operacional ou do gerenciador de credenciais em vez de alterar URLs remotos aleatórios.

Também verifique o remoto:

git remote -v

SSH e HTTPS usam caminhos de autenticação diferentes. Se um repositório usa [email protected]:org/repo.git e outro usa https://github.com/org/repo.git, eles não usarão necessariamente as mesmas credenciais.

Uma Rotina Confiável de Depuração

Quando a configuração do Git parece inconsistente, use uma rotina em vez de adivinhar:

  1. Execute o comando que falha a partir da raiz do repositório.
  2. Inspecione a configuração exata com git config --show-origin --get <nome>.
  3. Liste as configurações relacionadas com git config --list --show-origin --show-scope.
  4. Verifique a configuração local em .git/config antes de alterar a configuração global.
  5. Verifique inclusões condicionais se o problema só acontece em um diretório.
  6. Faça a menor alteração de configuração e execute novamente o comando original.

A configuração do Git é poderosa porque pode ser em camadas. Isso também é o que a torna confusa. A correção é tornar as camadas visíveis, depois alterar a camada que está realmente vencendo.

Quando a Configuração é Diferente Dentro de um IDE

Uma classe confusa de problemas do Git aparece apenas dentro de um editor ou GUI. O terminal usa uma identidade, mas o IDE faz commit com outra. Um hook passa no seu shell, mas falha no painel de commit. Um prompt de credencial aparece no terminal, enquanto a GUI tenta silenciosamente novamente com um token antigo.

A razão geralmente é o ambiente. Seu shell interativo pode carregar .bashrc, .zshrc, gerenciadores de SDK, gerenciadores de versão de linguagem e entradas PATH personalizadas. Uma GUI iniciada a partir da área de trabalho pode não carregar nada disso. O Git lê os mesmos arquivos de configuração, mas hooks e credential helpers podem ver um mundo diferente.

Para depurar, crie um hook temporário que imprime o ambiente em um arquivo local:

#!/usr/bin/env bash
{
  date
  pwd
  git --version
  git config --list --show-origin
  env | sort
} > /tmp/git-hook-debug.log
exit 1

Execute a ação do Git a partir do IDE, depois inspecione /tmp/git-hook-debug.log. Remova o hook depois. Isso informa o que o Git e o hook realmente viram, em vez do que seu terminal vê.

Para problemas de identidade em clientes GUI, verifique se a ferramenta tem suas próprias configurações do Git. Alguns clientes usam o Git do sistema; outros empacotam o Git ou armazenam a identidade do usuário nas preferências do aplicativo. Se o cliente está fazendo commit através do Git, git log --format=fuller -1 mostrará o autor e committer resultantes. Isso ajuda a separar "a configuração do Git estava errada" de "a GUI usou sua própria configuração".

Quando em dúvida, torne as configurações locais do repositório explícitas para projetos importantes:

git config --local user.email "[email protected]"
git config --local core.hooksPath .githooks

A configuração local reduz surpresas porque viaja com os metadados do repositório naquela máquina. Ainda não é commitada, então regras compartilhadas devem viver em arquivos rastreados como .gitattributes, .editorconfig, scripts de hook e documentação do projeto.

Mantenha uma Base Conhecida e Funcional

Quando problemas de configuração continuam voltando, salve uma pequena base conhecida e funcional para suas próprias máquinas. Não precisa ser sofisticada. Um ~/.gitconfig comentado com sua identidade, editor, comportamento padrão de branch, credential helper e includes é suficiente. Então, quando um novo laptop se comportar de forma diferente, você pode comparar em vez de redescobrir cada configuração.

Verificações úteis de base incluem:

git config --global --list --show-origin
git config --global --get core.editor
git config --global --get init.defaultBranch
git config --global --get-all credential.helper

Cuidado ao copiar configurações da internet ou de um colega. Aliases podem assumir ferramentas que você não tem. Credential helpers são específicos da plataforma. Configurações de final de linha podem estar certas para o SO deles e erradas para o seu. Trate a configuração do Git como a configuração do shell: pegue ideias emprestadas, mas entenda cada linha antes de mantê-la.

Para mantenedores de projeto, a melhor correção é mover expectativas compartilhadas para fora da configuração pessoal. Coloque finais de linha em .gitattributes, formatação na configuração do formatador, arquivos ignorados em .gitignore e verificações necessárias no CI. Quanto menos um projeto depender de configurações globais invisíveis, menos tickets de configuração ele criará.

Quando você alterar uma configuração para corrigir um problema, anote se foi local ou global. Muitos mistérios futuros do Git começam com uma boa correção local temporária que ninguém lembra seis meses depois.