Назад в блог

fatal: not a git repository — как починить за 60 секунд

28 сентября 2026 г.

это помогло?

Быстрейший способ потерять двадцать минут — набрать git pull в папке над вашим репозиторием. Git отвечает fatal: not a git repository (or any of the parent directories): .git, и большинство ответов в сети советует git init — что неверно для трёх из четырёх реальных причин.

Триаж за 60 секунд:

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

Если репозиторий существует выше, --show-toplevel печатает его корень — не та папка, дело закрыто, cd туда. Если падает и он, та же команда покажет содержимое папки: нет .git в списке — репозитория здесь никогда и не было. Одна команда отделяет две причины, за которыми большинство случаев. Остальная часть поста — про более редкие.

Почему Git пишет «fatal: not a git repository»?

Git находит репозиторий, поднимаясь от текущего каталога в поисках записи .git, и останавливается на первой. Этот подъём ломается ровно четырьмя способами: вы снаружи дерева, каталога .git больше нет, переменная окружения увела поиск в сторону, либо .git есть, но указывает в никуда. По опросу Stack Overflow 2022 года Git стоит примерно на 94% машин разработчиков — ошибка эта общий обряд посвящения. Выучите четыре случая один раз, и перестанут тратиться время и нервы.

(Если с репозиторием всё в порядке и вы пришли отменить коммит, страница Undo Anything in Git собирает все способы починки с этого сайта в одном месте.)

Случай 1: вы не в том каталоге

Самый частый. Две формы:

  1. Вы сделали cd в подкаталог — docs/, src/api/ — а привычка с другого проекта подсказывает, что корень здесь. Git поднимается, не находит ничего, сдаётся.
  2. Вы склонировали репозиторий и ждали файлы здесь, но git clone всегда создаёт подкаталог с именем репозитория. Checkout лежит уровнем ниже.
git rev-parse --show-toplevel   # печатает корень, когда он есть
cd "$(git rev-parse --show-toplevel)"  # прыжок туда одной командой

Вторая команда навсегда лечит проблему мышечной памяти: работает с любой глубины внутри репозитория.

Случай 2: нет .git — папка никогда не была репозиторием

ls -a не показывает .git. Обычно это:

  • ZIP с GitHub. Code → Download ZIP отдаёт только файлы: без .git, без истории, без remote. Документация GitHub это подтверждает: ZIP-архив содержит лишь снимок кода.
  • Файлы, скопированные с другой машины или из другого проекта, без скрытого каталога.
  • Чистильщик удалил .git как «бесполезную скрытую папку».

Починка: клонировать заново, история вернётся.

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

git init здесь начинает совершенно новый репозиторий; ничего не возвращается. А куча скопированных файлов обычно тянет за собой неотслеживаемые; git remove untracked files прикроет уборку, когда клон встанет на место.

git init не чинит репозиторий — он создаёт пустой там, где вы стоите.

Случай 3: GIT_DIR экспортирован и ломает все репозитории

Примета: ошибка следует за вами в каталоги, где час назад всё работало. Экспортированный GIT_DIR велит Git смотреть на один фиксированный путь вместо поиска репозитория, и каждый «обычный» каталог становится «not a repository».

env | grep GIT_DIR     # GIT_DIR=/какой-то/старый/путь
unset GIT_DIR

Если возвращается каждое утро — строка в ~/.bashrc, ~/.zshrc или CI-обёртке его экспортирует. Системы CI ставят GIT_DIR намеренно: внутри пайплайна это правильно, в интерактивном shell — мина.

Случай 4: submodule не инициализирован

Вы заходите в vendor/libfoo/, и Git говорит, что каталог не репозиторий. Он прав: до инициализации каталог submodule — пустая папка со строкой в .gitmodules и без единого checkout.

cat .gitmodules        # перечисляет пути submodule
git submodule update --init --recursive

Запускайте из корня репозитория, не изнутри submodule — правило подъёма действует и тут, а пустому submodule некуда подниматься.

Случай 5: .git — файл, и его цель исчезла

Worktree и submodule делают .git однострочным файлом: gitdir: /путь/к/настоящему/gitdir. Когда настоящий gitdir удалён (чистка .git/modules, переезд диска), указатель висит, и подъём находит .git, который не отвечает:

$ ls -la .git
-rw-r--r-- 1 you you 35 Sep 28 10:12 .git     # файл, а не каталог
$ cat .git
gitdir: ../.git/modules/libfoo
git worktree repair    # перевязывает worktree со сменившимися путями

Если worktree repair не находит цель — gitdir потерян. История submodule живёт в .git/modules/<имя> родительского репозитория; проверьте, что она там, прежде чем хоронить всё.

Симптом → причина → починка

СимптомВероятная причинаПочинка
Ошибка в одном проекте, ls -a без .gitZIP / скопированные файлызаново git clone
Ошибка из подкаталога, корень работаетВы снаружи дереваcd "$(git rev-parse --show-toplevel)"
Ошибка везде, даже там, где работалоЭкспортирован GIT_DIRunset GIT_DIR, вычистить из профиля shell
Ошибка внутри каталога submodulesubmodule не инициализированgit submodule update --init --recursive
.git — файл, ошибка остаётсяВисячий указатель worktree/submodulegit worktree repair, иначе заново клонировать

Так когда git init всё-таки верное решение?

Один раз: когда ls -a не показывает .git, а вы и собирались начать здесь новый репозиторий. Запускайте — и следующая команда git add, а не git log.

Во всех остальных случаях это ловушка с подписью. git init на каталог глубже строит вложенный репозиторий без коммитов — и следующий git log ответит fatal: your current branch 'main' does not have any commits yet. Эта ошибка значит: вы только что создали репозиторий там, где стояли, а настоящий — уровнем выше. Уборка хирургическая:

cd вложенный-каталог
rm -rf .git    # удаляет только случайный репозиторий, файлы целы

Проверьте строку приглашения перед этим rm: он должен выполняться внутри вложенного каталога, никогда — в корне проекта. Затем cd в настоящий корень и подтвердите через git rev-parse --show-toplevel, что Git находит то, что должен был найти с самого начала.

FAQ

Почему git status пишет fatal: not a git repository?

Git ищет каталог .git в текущей папке и во всех родительских. Нет .git нигде вверх по дереву — нет репозитория: обычно вы не в той папке, либо проект приехал без своей истории.

Чинит ли git init ошибку fatal: not a git repository?

Только там, где репозитория никогда не было. init создаёт новый пустой репозиторий и не может вернуть историю откуда-то ещё. Запустите его на каталог глубже — получите вложенный репозиторий без единого коммита.

Как исправить ошибку внутри submodule?

Из корня репозитория: git submodule update --init --recursive. До этого каталог submodule пуст, и Git называет его not a repository.

Почему ошибка появляется в каждом репозитории на машине?

Экспортированная переменная GIT_DIR подменяет поиск репозитория везде. Выполните env | grep GIT_DIR, затем unset GIT_DIR — и уберите её из профиля shell, если она возвращается.

— mrsaynothing

$ Следующий гайд — на почту

Одно письмо на пост. Починил — пошёл дальше.

self-hosted · никаких третьих сторон · отписка в один клик

что это?