Volver al blog

Fatal: Not a Git Repository? La solución en 60 segundos

28 de septiembre de 2026

¿esto lo arregló?

La forma más rápida de perder veinte minutos: escribir git pull en la carpeta de arriba de tu repo. Git responde fatal: not a git repository (or any of the parent directories): .git, y casi todas las respuestas en línea rematan con git init — que está mal en tres de las cuatro causas reales.

El triaje de 60 segundos:

git rev-parse --show-toplevel || ls -a

--show-toplevel imprime la raíz del repositorio cuando existe uno arriba tuyo: carpeta equivocada, caso cerrado, cd y listo. Si también falla, la misma línea lista el contenido de la carpeta: si no hay .git en esa lista, nunca hubo un repo aquí que encontrar. Ese único comando separa las dos causas que explican la mayoría de los casos. El resto del post cubre los casos más raros.

¿Por qué Git dice “fatal: not a git repository”?

Git encuentra un repositorio subiendo desde el directorio actual en busca de una entrada .git, y se detiene en la primera. Esa subida se rompe de exactamente cuatro maneras: estás fuera del árbol, la carpeta .git desapareció, una variable de ambiente desvía la búsqueda, o .git existe pero no apunta a nada. La encuesta de Stack Overflow de 2022 contaba Git en cerca del 94% de las máquinas de desarrolladores: el error es un rito de paso colectivo. Aprende los cuatro casos una vez y dejan de costarte tiempo.

(Si tu repo está bien y en realidad venías a deshacer un commit, Undo Anything in Git reúne todas las reparaciones del sitio en un solo lugar.)

Caso 1: estás en la carpeta equivocada

El más común. Dos formas:

  1. Hiciste cd a una subcarpeta — docs/, src/api/ — y la costumbre de otro proyecto te dice que la raíz está aquí. Git sube, no encuentra nada, se rinde.
  2. Clonaste un repo y esperabas ver los archivos aquí, pero git clone siempre crea un subdirectorio con el nombre del repo. El checkout queda un nivel más abajo.
git rev-parse --show-toplevel   # imprime la raíz cuando existe
cd "$(git rev-parse --show-toplevel)"  # salta ahí en un paso

El segundo comando arregla para siempre el problema de memoria muscular: funciona desde cualquier profundidad dentro del repo.

Caso 2: no hay .git — la carpeta nunca fue un repo

ls -a no muestra .git. Normalmente:

  • Un ZIP descargado de GitHub. Code → Download ZIP entrega solo los archivos: sin .git, sin historial, sin remote. La documentación de GitHub lo confirma: el archivo ZIP contiene únicamente la instantánea del código.
  • Archivos copiados desde otra máquina u otro proyecto, sin la carpeta oculta.
  • Una herramienta de limpieza borró .git como “carpeta oculta inservible”.

Arreglo: vuelve a clonar para recuperar el historial.

cd ..
git clone https://github.com/<user>/<repo>.git

git init aquí empieza un repositorio nuevo; nada se recupera. Y el desorden de archivos copiados suele arrastrar archivos sin seguimiento; git remove untracked files cubre la limpieza cuando el clone esté listo.

git init no repara un repo — crea uno vacío donde estás parado.

Caso 3: GIT_DIR está exportada y rompe todos los repos

La pista: el error te sigue a directorios donde Git funcionaba hace una hora. Un GIT_DIR exportada le dice a Git que mire una ruta fija en vez de descubrir el repo, y cada directorio “normal” se vuelve “not a repository”.

env | grep GIT_DIR     # GIT_DIR=/una/ruta/vieja
unset GIT_DIR

Si vuelve cada mañana, una línea en ~/.bashrc, ~/.zshrc o un wrapper de CI la exporta. Los sistemas de CI ponen GIT_DIR a propósito: correcto dentro del pipeline, mina terrestre en tu shell interactivo.

Caso 4: el submodule nunca se inicializó

Entras a vendor/libfoo/, y Git dice que el directorio no es un repositorio. Es cierto: antes de inicializarse, una carpeta de submodule es una carpeta vacía con una línea en .gitmodules y nada descargado.

cat .gitmodules        # lista las rutas de los submodules
git submodule update --init --recursive

Ejecútalo desde la raíz del repo, no desde el submodule — la regla de subida aplica, y un submodule vacío no tiene raíz a la cual subir.

Caso 5: .git es un archivo, y su objetivo desapareció

Los worktrees y los submodules convierten .git en un archivo de una línea: gitdir: /ruta/al/gitdir/real. Cuando el gitdir real se borra (un .git/modules limpiado, un disco movido), el puntero queda colgando y la subida encuentra un .git que no responde nada:

$ ls -la .git
-rw-r--r-- 1 you you 35 Sep 28 10:12 .git     # un archivo, no un directorio
$ cat .git
gitdir: ../.git/modules/libfoo
git worktree repair    # reenlaza worktrees cuyas rutas cambiaron

Si worktree repair no encuentra el objetivo, el gitdir se perdió. En submodules, el historial vive en el .git/modules/<nombre> del repo padre; verifica que exista antes de asumir lo peor.

Síntoma → causa → arreglo

SíntomaCausa probableArreglo
Error en un proyecto, ls -a sin .gitZIP descargado / archivos copiadosgit clone otra vez
Error desde una subcarpeta, la raíz funcionaFuera del árbolcd "$(git rev-parse --show-toplevel)"
Error en todos los directorios, hasta los que funcionabanGIT_DIR exportadaunset GIT_DIR, purga del perfil de shell
Error dentro de una carpeta de submoduleSubmodule sin inicializargit submodule update --init --recursive
.git es un archivo, el error persistePuntero worktree/submodule colgantegit worktree repair, si no re-clone

Entonces, ¿git init es alguna vez el arreglo correcto?

Una vez: cuando ls -a no muestra .git y piensas empezar un repositorio nuevo aquí. Ejecútalo, y el siguiente comando es git add, no git log.

En todos los demás casos es una trampa con firma. git init una carpeta muy adentro construye un repo anidado sin commits — y tu próximo git log responde fatal: your current branch 'main' does not have any commits yet. Ese error significa que acabas de crear un repositorio donde estabas parado, y el real está un nivel arriba. La limpieza es quirúrgica:

cd la-carpeta-anidada
rm -rf .git    # borra solo el repo accidental, archivos intactos

Revisa el prompt antes de ese rm: debe correr dentro de la carpeta anidada, nunca en la raíz del proyecto. Luego cd a la raíz real y confirma con git rev-parse --show-toplevel que Git encuentra lo que siempre debió encontrar.

FAQ

¿Por qué git status dice fatal: not a git repository?

Git busca un directorio .git en la carpeta actual y en cada padre. Si no hay .git en ningún punto del árbol, no hay repositorio: normalmente estás en la carpeta equivocada, o el proyecto llegó sin su historial.

¿git init arregla fatal: not a git repository?

Solo donde nunca existió un repo. init crea un repositorio nuevo y vacío, incapaz de recuperar historial de otro lado. Si lo ejecutas una carpeta más adentro, terminas con un repo anidado sin ningún commit.

¿Cómo arreglo el error dentro de un submodule?

Desde la raíz del repo: git submodule update --init --recursive. La carpeta de un submodule queda vacía hasta entonces, y Git la declara not a repository.

¿Por qué el error aparece en todos los repositorios de mi máquina?

Una variable GIT_DIR exportada anula el descubrimiento de repos en todas partes. Corre env | grep GIT_DIR, luego unset GIT_DIR — y bórrala de tu perfil de shell si vuelve.

— mrsaynothing

$ Recibe el próximo how-to por email

Un email por post. Arréglalo y sigue.

self-hosted · sin terceros · baja con un clic

¿qué es esto?