Solución de Problemas de Configuración de Git: Correcciones Comunes y Mejores Prácticas

Soluciona problemas de configuración de Git rastreando orígenes de ajustes, resolviendo problemas de identidad, alias, hooks, finales de línea, pull y credenciales.

Solución de Problemas de Configuración de Git: Correcciones Comunes y Mejores Prácticas

La mayoría de los problemas de configuración de Git parecen más extraños de lo que realmente son. Git generalmente está haciendo exactamente lo que uno de sus archivos de configuración le indicó. La parte difícil es encontrar qué archivo, porque la configuración puede estar en el repositorio, tu configuración de usuario, una configuración del sistema, un archivo incluido, o una inclusión condicional que solo aplica bajo un directorio.

El comando al que recurro primero es este:

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

Si tu versión de Git no soporta --show-scope, usa:

git config --list --show-origin

El origen te dice qué archivo proporcionó cada valor. Eso importa más que el valor solo. Ver [email protected] no es suficiente; necesitas saber si vino de .git/config, ~/.gitconfig, /etc/gitconfig, o un perfil de trabajo incluido.

La configuración de Git tiene un orden de prioridad. La configuración local del repositorio normalmente supera a la configuración global del usuario, y la configuración global supera a la del sistema. Las opciones de línea de comandos y las variables de entorno pueden anular todas ellas para un solo comando. Las inclusiones condicionales agregan otra capa: un archivo global puede decir, "Cuando estoy dentro de este directorio, carga también esta otra configuración".

Puedes inspeccionar una configuración con su origen:

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

Ese hábito previene muchas ediciones innecesarias. Si un repositorio tiene user.email configurado localmente, cambiar git config --global user.email no afectará los commits en ese repositorio.

Nombre o Correo Electrónico Incorrecto en los Commits

El síntoma es simple: los commits muestran el autor incorrecto. Esto sucede a menudo cuando usas la misma laptop para proyectos laborales y personales, o cuando clonas un repositorio de la empresa antes de configurar tu correo laboral.

Verifica qué usará Git en el repositorio actual:

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

Configura tu identidad predeterminada globalmente:

git config --global user.name "Tu Nombre"
git config --global user.email "[email protected]"

Para un repositorio, configúralo localmente:

git config --local user.name "Tu Nombre"
git config --local user.email "[email protected]"

Si quieres que Git rechace commits cuando la identidad no está configurada explícitamente, usa:

git config --global user.useConfigOnly true

Esa configuración es útil para personas que cambian entre identidades. Puede molestar a los principiantes porque Git dejará de adivinar a partir del nombre de usuario del sistema y el nombre del host. Úsalo cuando prefieras fallar un commit antes que crear uno con la dirección incorrecta.

Para una separación más limpia entre trabajo y personal, usa inclusiones condicionales:

# ~/.gitconfig
[user]
    name = Tu Nombre
    email = [email protected]

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

Luego pon esto en ~/.gitconfig-trabajo:

[user]
    email = [email protected]

La barra inclinada al final en gitdir:~/trabajo/ importa porque significa repositorios bajo ese directorio. Si no se activa, ejecuta git config --list --show-origin desde dentro de un repositorio de trabajo y verifica si el archivo incluido aparece.

Si ya hiciste commits con el correo incorrecto, cambiar la configuración solo corrige commits futuros. Para commits no publicados, puedes enmendar o rebasar. Para commits ya enviados a una rama compartida, pregunta antes de reescribir la historia.

Alias Que No Funcionan

Los alias de Git se almacenan bajo alias.*. Listarlos así:

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

Un alias normal se expande a un subcomando de Git:

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

Si el alias necesita un pipeline de shell, expansión de variables, cd, u otro comando que no sea de Git, debe comenzar con !:

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

Sin !, Git intenta tratar la primera palabra como un comando de Git. ls -la se convierte en "ejecuta el comando de Git llamado ls", que no es lo que querías.

Las comillas son el otro fallo común. Si defines alias desde el shell, usa comillas simples alrededor de todo el alias cuando sea posible, luego comillas dobles dentro según sea necesario. Diferentes shells manejan las comillas de manera diferente, especialmente PowerShell y cmd.exe. Si un alias complejo sigue rompiéndose, edita el archivo de configuración directamente:

git config --global --edit

Un truco práctico de depuración es comenzar con el comando fuera de Git. Una vez que funciona, pégalo en el alias. Si es un alias de shell, prefíjalo con ! y prueba de nuevo.

También ten cuidado con alias que sombrean modelos mentales. Un alias llamado pull o merge puede hacer que el comportamiento de Git sea sorprendente. Git no permite que los alias anulen comandos incorporados directamente, pero los alias de shell y los scripts envolventes sí pueden. Si git pull se comporta de manera extraña, verifica también tu configuración del shell:

type git
alias | grep git

Hooks Que Nunca Se Ejecutan

Los hooks fallan por tres razones aburridas: Git está buscando en un directorio de hooks diferente, el archivo no es ejecutable, o el script asume un entorno que no tiene.

Verifica la ruta de hooks configurada:

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

Si esto imprime .githooks, Git usará .githooks/pre-commit, no .git/hooks/pre-commit. Si no imprime nada, Git usa .git/hooks.

En macOS y Linux, verifica los permisos:

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

Un hook que sale con un estado distinto de cero bloquea la operación de Git. Agrega rastreo temporal cerca de la parte superior:

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

No dejes rastreo ruidoso en un hook compartido. Se vuelve ilegible rápidamente.

Los problemas de ruta son comunes con clientes GUI. Un hook que funciona en tu terminal puede fallar en un IDE porque el IDE no cargó tu perfil de shell. Prefiere comandos locales del proyecto cuando sea posible:

./node_modules/.bin/eslint .

o verifica el comando e imprime un mensaje útil:

if ! command -v npm >/dev/null 2>&1; then
  echo "npm es necesario para este hook pero no se encontró en PATH."
  exit 1
fi

Los Finales de Línea Siguen Cambiando

Los problemas de finales de línea se manifiestan como archivos que aparecen modificados inmediatamente después del checkout, diferencias grandes donde cada línea cambió, o scripts que fallan en Linux después de ser editados en Windows.

Verifica tu configuración:

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

Las opciones comunes son:

# Checkout amigable para Windows, LF en el repositorio
git config --global core.autocrlf true

# Amigable para macOS/Linux: convertir CRLF a LF solo al commit
git config --global core.autocrlf input

# Sin conversión automática
git config --global core.autocrlf false

Para un equipo, .gitattributes es más confiable que decirle a cada desarrollador que configure globales correctamente. Pon las reglas del proyecto en el repositorio:

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

Después de agregar o cambiar .gitattributes, normaliza los archivos deliberadamente:

git add --renormalize .
git status

Revisa esa diferencia cuidadosamente. Puede tocar muchos archivos, y no quieres mezclar la normalización de finales de línea con trabajo de características.

Pull, Push o Merge Usa el Valor Predeterminado Incorrecto

A veces el problema de configuración no es la identidad o los finales de línea. Es Git eligiendo una estrategia de pull que no esperabas.

Verifica las configuraciones relacionadas con pull:

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

Si git pull sigue rebasando cuando esperabas un merge, pull.rebase o una configuración específica de rama puede estar habilitada. Si rechaza pulls que no son fast-forward, pull.ff=only puede estar configurado. Estas configuraciones no son incorrectas por sí mismas; solo necesitan coincidir con el flujo de trabajo del equipo.

Establece un valor predeterminado explícito en lugar de vivir con advertencias y sorpresas:

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

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

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

Para una rama:

git config branch.main.rebase true

Confusión con el Ayudante de Credenciales

Los problemas de autenticación a menudo parecen problemas remotos pero provienen de la configuración local. Git puede usar un ayudante de credenciales que tiene un token antiguo en caché.

Verifica los ayudantes:

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

Puedes ver osxkeychain, manager, manager-core, store o cache. Pueden existir múltiples ayudantes. Si Git sigue enviando la credencial incorrecta, elimínala del llavero del sistema o del administrador de credenciales en lugar de cambiar URLs remotas aleatorias.

También verifica el remoto:

git remote -v

SSH y HTTPS usan diferentes rutas de autenticación. Si un repositorio usa [email protected]:org/repo.git y otro usa https://github.com/org/repo.git, no necesariamente usarán las mismas credenciales.

Una Rutina de Depuración Confiable

Cuando la configuración de Git se siente inconsistente, usa una rutina en lugar de adivinar:

  1. Ejecuta el comando que falla desde la raíz del repositorio.
  2. Inspecciona la configuración exacta con git config --show-origin --get <nombre>.
  3. Lista las configuraciones relacionadas con git config --list --show-origin --show-scope.
  4. Verifica la configuración local en .git/config antes de cambiar la configuración global.
  5. Verifica las inclusiones condicionales si el problema solo ocurre bajo un directorio.
  6. Haz el cambio de configuración más pequeño y vuelve a ejecutar el comando original.

La configuración de Git es poderosa porque puede ser en capas. También es por eso que se vuelve confusa. La solución es hacer visibles las capas, luego cambiar la capa que realmente está ganando.

Cuando la Configuración es Diferente Dentro de un IDE

Una clase confusa de problemas de Git aparece solo dentro de un editor o GUI. El terminal usa una identidad, pero el IDE hace commits con otra. Un hook pasa en tu shell, pero falla desde el panel de commits. Un mensaje de credencial aparece en el terminal, mientras que la GUI reintenta silenciosamente con un token antiguo.

La razón suele ser el entorno. Tu shell interactivo puede cargar .bashrc, .zshrc, administradores de SDK, administradores de versiones de lenguaje y entradas PATH personalizadas. Una GUI lanzada desde el escritorio puede no cargar nada de eso. Git lee los mismos archivos de configuración, pero los hooks y ayudantes de credenciales pueden ver un mundo diferente.

Para depurarlo, crea un hook temporal que imprima el entorno en un archivo local:

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

Ejecuta la acción de Git desde el IDE, luego inspecciona /tmp/git-hook-debug.log. Elimina el hook después. Esto te dice lo que Git y el hook realmente vieron, en lugar de lo que ve tu terminal.

Para problemas de identidad en clientes GUI, verifica si la herramienta tiene sus propias configuraciones de Git. Algunos clientes usan Git del sistema; otros incluyen Git o almacenan la identidad del usuario en las preferencias de la aplicación. Si el cliente está haciendo commits a través de Git, git log --format=fuller -1 mostrará el autor y committer resultantes. Eso ayuda a separar "la configuración de Git estaba mal" de "la GUI usó su propia configuración".

Cuando tengas dudas, haz explícitas las configuraciones locales del repositorio para proyectos importantes:

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

La configuración local reduce sorpresas porque viaja con los metadatos del repositorio en esa máquina. Aún así no se confirma, por lo que las reglas compartidas deben vivir en archivos rastreados como .gitattributes, .editorconfig, scripts de hook y documentación del proyecto.

Mantén una Línea Base Conocida y Funcional

Cuando los problemas de configuración siguen regresando, guarda una pequeña línea base conocida y funcional para tus propias máquinas. No necesita ser elegante. Un ~/.gitconfig comentado con tu identidad, editor, comportamiento predeterminado de rama, ayudante de credenciales e inclusiones es suficiente. Luego, cuando una nueva laptop se comporte de manera diferente, puedes comparar en lugar de redescubrir cada configuración.

Las verificaciones útiles de línea base incluyen:

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

Ten cuidado al copiar configuraciones de internet o de un compañero de trabajo. Los alias pueden asumir herramientas que no tienes. Los ayudantes de credenciales son específicos de la plataforma. Las configuraciones de finales de línea pueden ser correctas para su sistema operativo e incorrectas para el tuyo. Trata la configuración de Git como la configuración del shell: toma prestadas ideas, pero entiende cada línea antes de mantenerla.

Para los mantenedores de proyectos, la mejor solución es mover las expectativas compartidas fuera de la configuración personal. Pon los finales de línea en .gitattributes, el formato en la configuración del formateador, los archivos ignorados en .gitignore y las verificaciones requeridas en CI. Cuanto menos dependa un proyecto de configuraciones globales invisibles, menos tickets de configuración creará.

Cuando cambies una configuración para solucionar un problema, anota si era local o global. Muchos misterios futuros de Git comienzan con una buena solución temporal local que nadie recuerda seis meses después.