Файл .gitignore и удаление файлов из индекса

В проектах бывают файлы и каталоги, которые не следует помещать в коммиты. Например, скомпилированные исполняемые файлы, папки с настройками среды разработки, временные файлы.

При этом неудобно, чтобы такие объекты постоянно висели в области неотслеживаемых. Ведь тогда придется себя ограничить на использование команды git add --all и подобных, при которых в область индексирования попадает все сразу.

Для решения этой проблемы в git-репозиториях создают файл .gitignore. В нем указывают файлы и каталоги, котороые Git должен игнорировать в принципе.

$ touch only_my_notes.txt
$ git status
Текущая ветка: master
Неотслеживаемые файлы:
  (используйте «git add <файл>...», чтобы добавить в то, что будет включено в коммит)
    only_my_notes.txt

индекс пуст, но есть неотслеживаемые файлы
 (используйте «git add», чтобы проиндексировать их)
$ vim .gitignore
$ cat .gitignore 
only_my_notes.txt
$ git status
Текущая ветка: master
Неотслеживаемые файлы:
  (используйте «git add <файл>...», чтобы добавить в то, что будет включено в коммит)
    .gitignore

индекс пуст, но есть неотслеживаемые файлы
 (используйте «git add», чтобы проиндексировать их)

В примере выше только что созданный файл only_my_notes.txt сначала виден в неотслеживаемых. Однако после того, как в файле .gitignore указывается его имя, Git начинает его игнорировать. В то же время, так как мы создали сам файл .gitignore, уже он появляется в неотслеживаемых. Может возникнуть вопрос: следует ли включать в коммиты .gitignore? Да, обычно его включают в область индексирования и, следовательно, коммиты.

В .gitignore не обязательно указывать каждый файл отдельно. Существуют специальные правила и шаблоны. Так, если следует игнорирвать целый каталог, можно просто написать его имя. Однако надо поставить в конце /, чтобы отличать от файлов с таким же именем. Если указано имя файла без адреса, то будут проигнорированы все файлы с таким именем во всех подкаталогах проекта.

Случается, что файл, который надо игнорировать, уже был отправлен в индекс. С одной стороны, мы не можем удалить его из проекта, так как он необходим. С другой - его необходимо исключить из коммитов. По-крайней мере, следующих.

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

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

$ git rm --cached docs/part1.txt 
rm 'docs/part1.txt'
$ ls docs/part1.txt 
docs/part1.txt
$ git status
Текущая ветка: master
Изменения, которые будут включены в коммит:
  (используйте «git restore --staged <файл>...», чтобы убрать из индекса)
    новый файл:    .gitignore
    удалено:       docs/part1.txt

$ git commit -m "тест удаления из индекса"
[master b2792ec] тест удаления из индекса
 2 files changed, 3 insertions(+)
 create mode 100644 .gitignore
 delete mode 100644 docs/part1.txt
$ vim docs/part1.txt 
$ git status
Текущая ветка: master
нечего коммитить, нет изменений в рабочем каталоге