Git: как убрать файл из репозитория, оставив его на диске

Категория: Git · Язык: Bash · Обновлено:

Чтобы перестать отслеживать файл и не удалять его с диска, выполните git rm --cached путь/к/файлу. Затем добавьте путь в .gitignore и сделайте коммит. Без этих двух шагов git продолжит показывать файл в изменениях.

Убрать один файл из репозитория

Bash
git rm --cached config/local.env      # убрать из индекса, файл на диске остаётся
echo "config/local.env" >> .gitignore # чтобы git больше не предлагал его добавить
git add .gitignore
git commit -m "Перестать отслеживать config/local.env"

Убрать папку целиком

Bash
git rm -r --cached build/
echo "build/" >> .gitignore
git add .gitignore
git commit -m "Убрать build/ из репозитория"

Почему .gitignore не работает

Файл .gitignore действует только на неотслеживаемые файлы. Если файл уже попал в репозиторий, git продолжает следить за ним, как бы ни был записан шаблон. Проверить причину помогают две команды:

Bash
git ls-files config/local.env      # если команда вывела путь, файл отслеживается
git check-ignore -v --no-index config/local.env   # покажет правило, которое игнорирует файл

Если первая команда выводит путь, нужен git rm --cached. Флаг --no-index нужен потому, что для уже отслеживаемого файла check-ignore без него молчит.

Обновить индекс по всему .gitignore

Когда в .gitignore добавили много правил и хочется разом убрать все лишние файлы, пересоберите индекс:

Bash
git rm -r --cached .
git add .
git commit -m "Применить обновлённый .gitignore"

Секреты и история

git rm --cached убирает файл только из следующих коммитов. В старых коммитах он остаётся, поэтому пароли и ключи, попавшие в репозиторий, нужно считать скомпрометированными и заменить. Удалять их из истории нужно отдельными инструментами, например git filter-repo.

Частые вопросы

Чем отличается git rm от git rm --cached?

Без --cached git удаляет файл и из индекса, и с диска. С --cached файл остаётся на диске, пропадает только слежение за ним.

Как вернуть слежение за файлом?

Уберите правило из .gitignore и выполните git add путь/к/файлу, либо git add -f путь/к/файлу, если файл по-прежнему игнорируется.