Introducción
Todo lo que Git sabe sobre un repositorio vive en .git/. Conocer qué es cada entrada quita el misterio del diagnóstico "¿qué acaba de pasar?".
Disposición de nivel superior
.git/
HEAD # ref simbólica al branch actual
config # configuración local del repositorio
description # usado por gitweb
index # el área de staging
packed-refs # refs de branch y tag empaquetadas (opcional)
hooks/ # scripts hook del lado del cliente
info/ # archivo de excludes y otra info local del repo
logs/ # reflogs
objects/ # todos los objetos (sueltos + pack/)
refs/ # branches, tags, seguimiento remoto
worktrees/ # worktrees vinculados (si los hay)
modules/ # directorios .git de submódulos
HEAD y refs
cat .git/HEAD
ls .git/refs/heads
ls .git/refs/remotes/origin
ls .git/refs/tags
cat .git/packed-refs | head
objects/
Objetos sueltos bajo objects/xx/, objetos empaquetados en objects/pack/. No tocar a mano.
logs/
El reflog. logs/HEAD registra cada movimiento de HEAD; logs/refs/heads/<branch> registra el historial de cada branch.
cat .git/logs/HEAD | head
hooks/
Scripts hook de muestra, todos llamados *.sample por defecto. Para habilitar, quita el sufijo y hazlo ejecutable:
cd .git/hooks
cp pre-commit.sample pre-commit
chmod +x pre-commit
info/
info/exclude es un archivo ignore por repo y por clon (no commiteado). info/refs es generado por git update-server-info para servidores HTTP dumb.
config
Configuración local en formato INI. Edita vía git config --local o git config -e:
cat .git/config
git config --local user.email "[email protected]"
worktrees/
Cada worktree vinculado tiene un directorio bajo .git/worktrees/<name>/ con su propio HEAD, index y logs.
modules/
Para repos con submódulos, el directorio .git de cada submódulo vive aquí, y el árbol de trabajo del submódulo contiene un pequeño archivo .git que apunta a él.
Repositorios bare
Un repo bare tiene los mismos contenidos pero a nivel superior (sin envoltorio .git/) y sin árbol de trabajo. Convención: nombra el directorio project.git.
git rev-parse para paths
Los scripts que necesitan encontrar paths dentro de .git/ nunca deben asumir que el directorio se llama literalmente .git. Los submódulos usan un archivo .git que apunta a otro lugar; los worktrees tienen gitdirs vinculados; los repos bare no tienen gitdir separado. Usa git rev-parse:
git rev-parse --git-dir # gitdir real para el repo actual
git rev-parse --git-common-dir # dir compartido para worktrees
git rev-parse --show-toplevel # raíz del árbol de trabajo
git rev-parse --is-inside-git-dir
git rev-parse --is-inside-work-tree
Estas cinco preguntas cubren casi cada verificación de "¿dónde estoy?" que un script necesita.
Errores comunes
Editar archivos dentro de .git/ directamente. Casi todo tiene un comando Git que lo hace correctamente, atómicamente y con hooks. Hacer copia de seguridad solo del árbol de trabajo y olvidar que .git/ contiene todo el historial; respalda el directorio entero. Compartir .git/hooks/ asumiendo que se propagan; los hooks no están versionados. Usa core.hooksPath o una herramienta como pre-commit para compartirlos. Finalmente, eliminar .git/index por impulso; reconstruye con git read-tree HEAD, pero solo después de respaldar.