Git добавить добавленные игнорируемые файлы
Я пытаюсь удалить ранее отслеживаемый каталог из git, который работает, но он добавляется обратно с каждым последующим git add .
, git add -A
и т.д. Вот что я сделал:
Добавить в .gitignore в корень проекта:
node_modules
Выполните следующее:
git rm -r --cached node_modules
git commit -a -m "removed node_modules"
git push origin master
До сих пор так хорошо, что удаляет каталог из удаленного репозитория. Проблема в том, что когда я позже запускаю git status
, он сообщает мне, что каталог node_modules не проверен и продолжает добавлять его в будущие коммиты.
Что мне не хватает и/или как я могу найти корень моей проблемы?
Из здесь:
Команда git add не добавляет игнорируемые файлы по умолчанию.... Команда git add может использоваться для добавления игнорируемых файлов с параметром -f (force).
Дополнительная информация из комментариев:
Я отслеживаю файл .gitignore.
git check-ignore node_modules/
возвращает node_modules/как ожидалось.
Нет использования подмодулей.
Update:
Я создал образец, который, как представляется, реплицирует проблему, следуя приведенным выше шагам:
https://github.com/awhitehouse104/SampleRepo
Разрешение:
Чтобы обобщить ответ и комментарии ниже, проблема была в кодировке моего файла .gitignore. Я использовал echo 'node_modules' > .gitignore
для создания файла на окнах 8, и он появился как UTF-16 с спецификацией (согласно ответу ниже). После нескольких поисковых запросов Google кажется, что это кодировка по умолчанию с powershell, и я могу подтвердить, что сохранение, поскольку UTF-8, похоже, решило проблему.
TL;DR; Вероятно, не используйте этот метод создания файлов .gitignore или будьте готовы изменить кодировку
echo 'node_modules' > .gitignore
Ответы
Ответ 1
У вас, вероятно, есть отрицательное правило (правило include-again, которое начинается с !
) в вашем файле .gitignore
где-то после строки node_modules
.
git check-ignore
имеет ошибку/неоднозначность в документах. Вы ожидаете, что если git check-ignore node_modules/
печатает node_modules/
, то node_modules/
игнорируется. Но на самом деле он печатает путь, если этот путь соответствует любому шаблону игнорирования - положительному или отрицательному. Единственный способ убедиться в использовании опции -v
(--verbose
), которая сделает git check-ignore
распечатать соответствующий шаблон.
Более того, если git check-ignore -v
говорит, что каталог игнорируется, это не обязательно означает, что все файлы в этом каталоге игнорируются. Пример репо:
/
.git/
.gitignore
node_modules/
bar
foo
$ cat .gitignore
/node_modules/*
!/node_modules/foo
$ git check-ignore -v node_modules/
.gitignore:1:/node_modules/* node_modules/
^ positive pattern => ignored
$ git check-ignore -v node_modules/foo
.gitignore:2:!/node_modules/foo node_modules/foo
^ negative pattern => not ignored
$ git add -A
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: node_modules/foo
#
Итак, если git check-ignore -v node_modules/
говорит, что node_modules/
игнорируется, выполните git add -A node_modules/
, а затем запустите git check-ignore -v --no-index
в отношении отдельных добавленных файлов, чтобы узнать, почему они были добавлены.
Обновление: Я не ожидал, что: ваш файл .gitignore
находится в "UTF-16 с BOM (байтовый порядок)":
$ cat .gitignore | hexdump -vC
00000000 ff fe 6e 00 6f 00 64 00 65 00 5f 00 6d 00 6f 00 |..n.o.d.e._.m.o.|
00000010 64 00 75 00 6c 00 65 00 73 00 0d 00 0a 00 |d.u.l.e.s.....|
Вот почему git, вероятно, не справится с этим. Сохраните файл в UTF-8 без спецификации, который должен устранить проблему. Но я также предлагаю подавать отчет об ошибке в отношении git check-ignore
- в этом угловом случае его вывод явно не согласуется с тем, что фактически игнорирует git.
Ответ 2
Вы можете сделать
git check-ignore -v --no-index path/with/unexpected/result
чтобы узнать, почему git add
добавил или не добавил этот путь.
git check-ignore
docs.
В частности, вы хотите проверить, что фактически добавляется, а не каталог.
далее, do find . -name .git
. Субмодули - это вложенные репозитории, .gitmodules
и команда подмодуля удобны, но они просто помогают им.
Ответ 3
Добавьте файл в git ignore, затем
git update-index --assume-unchanged <file>
Ответ 4
Вот что я делаю, чтобы игнорировать папку node_modules после ее отслеживания.
-
Создайте файл .gitignore и добавьте к нему node_modules.
-
Зафиксируйте файл .gitignore. После этой точки все, что вы обновляете в папке node_modules, не появится в git status
.
-
Но это не удаляет то, что мы уже имеем на репо в папке node_modules. Итак, теперь нам нужно удалить все, что мы сделали ранее.
Для этого используйте git rm --cached node_modules -r
-
Теперь git status
покажет, что файлы удалены.
-
Используйте команду git commit -m "node_modules removed"
с любым сообщением.
Теперь все должно быть удалено из репо, и будущие изменения не будут отслеживаться.
Ответ 5
Другой подход, если вы не хотите использовать git rm --cached
rm -Rf node_modules
git add -u
git commit -m "stop tracking node_modules"
npm install
# done
Также обратите внимание на различие между node_modules и node_modules/, которое, похоже, имеет правильное значение. (Спасибо, спасибо за примечание об этом)
Ответ 6
gitignore - Указывает намеренно не проверенные файлы для игнорирования.
$HOME/.config/git/ignore, $GIT_DIR/info/exclude, .gitignore
Каждая строка в файле gitignore указывает шаблон. При решении вопроса о том, следует ли игнорировать путь, Git обычно проверяет шаблоны gitignore из нескольких источников со следующим порядком приоритета: от самого высокого до самого низкого (в пределах одного уровня приоритета последний шаблон соответствия решает исход):
Чтобы игнорировать весь каталог, вы должны использовать /**
,
Конечная/** соответствует всем внутри. Например, abc/** соответствует всем файлам внутри каталога "abc" относительно местоположения файла .gitignore с бесконечной глубиной.
или
Вы можете игнорировать весь каталог, добавив эту строку в свой корневой файл .gitignore:
/DIR_NAME
Вместо этого вы можете добавить файл /logs/ .gitignore, содержащий это:
[^.] *
Каталог останется в вашем репо, но все файлы внутри/будут игнорироваться. Легко!
Ниже приведены шаги, которые необходимо выполнить,
Пример, чтобы исключить все, кроме определенного каталога foo/bar (обратите внимание на /* - без косой черты, подстановочный знак также исключит все внутри foo/bar):
$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar
Ответ 7
Я создал репозиторий, чтобы попытаться дублировать вашу проблему, и я получил первый ответ от http://www.stackoverflow.com/questions/11451535/gitignore-not-working.
Здесь мое репо, если вам интересно: https://github.com/IAMZERG/so_project_gitignore
Попробуйте добавить это вместо .gitignore:
**/directory_to_remove
После этого запустите git rm --cached directory_to_remove -r
git статус должен показать, что вы удалили кучу файлов в каталоге, который вы пытаетесь удалить.
Затем, совершите и нажмите на свой пульт, и все должно быть золотым... Может быть?
Ответ 8
У меня была подобная проблема. Убедившись, что моя кодировка была ANSI, и окончание строк было Unix (LF), исправила мою проблему.
Ответ 9
Происхождение должно быть голым. Вот немного bash, чтобы продемонстрировать это. Не стесняйтесь редактировать его, если он не представляет ваш прецедент.
#!/bin/bash
rm -rf /tmp/git_test
mkdir /tmp/git_test/
git init --bare /tmp/git_test/primary_repo
# populate repo
cd /tmp/git_test/
git clone ./primary_repo ./secondary_repo
cd secondary_repo
echo hi_bob > some_content
mkdir node_modules
echo hi_dave > node_modules/moduleA
git add .
git commit -m "populated primary"
git push
# do the removal in tertiary
cd /tmp/git_test/
git clone ./primary_repo ./tertiary_repo
cd tertiary_repo
echo node_modules >> .gitignore
git add .gitignore
git rm -r --cached node_modules
git commit -a -m "removed node_modules"
git push origin master
rm -r node_modules
echo --------------------------------
echo git status:
git status