Вопрос: Как заставить Git «забыть» о файле, который был отслежен, но теперь находится в .gitignore?


Существует файл, который отслеживается git, но теперь файл находится на .gitignoreсписок.

Однако этот файл продолжает появляться в git statusпосле его редактирования. Как вы принуждаете gitполностью забыть об этом?


3530


источник


Ответы:


.gitignoreпредотвратит добавление ненужных файлов (без add -f) к набору файлов, отслеживаемых git, однако git продолжит отслеживать любые файлы, которые уже отслеживаются.

Чтобы остановить отслеживание файла, вам нужно удалить его из индекса. Это может быть достигнуто с помощью этой команды.

git rm --cached <file>

Удаление файла из ревизии главы произойдет при следующем фиксации.


3763



В приведенной ниже последовательности команд будут удалены все элементы из индекса Git (не из рабочего каталога или локального репо), а затем обновляется индекс Git, при этом игнорируется git. PS. Индекс = Кэш

Первый:

git rm -r --cached . 
git add .

Затем:

git commit -am "Remove ignored files"

1926



git update-index делает работу для меня:

git update-index --assume-unchanged <file>

Заметка: Это решение фактически независимо от .gitignoreпоскольку gitignore предназначен только для файлов без следа.

редактировать: Поскольку этот ответ был опубликован, был создан новый вариант, и это должно быть предпочтительным. Вы должны использовать --skip-worktreeкоторый предназначен для измененных отслежённых файлов, которые пользователь больше не хочет совершать и сохраняет --assume-unchangedдля повышения эффективности, чтобы предотвратить git, чтобы проверить статус больших отслеживаемых файлов. Видеть https://stackoverflow.com/a/13631525/717372 Больше подробностей...


725



git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

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


212



Я всегда использую эту команду, чтобы удалить эти необработанные файлы. Однострочный, Unix-стиль, чистый вывод:

git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

Он перечисляет все ваши проигнорированные файлы, заменяет каждую выходную строку на цитированную строку вместо того, чтобы обрабатывать пути с пробелами внутри и передавать все в git rm -r --cachedудалить пути / файлы / директории из индекса.


58



If you cannot git rm a tracked file because other people might need it (warning, even if you git rm --cached, when someone else gets this change, their files will be deleted in their filesystem) please look at https://gist.github.com/1423106 for ways people have worked around the problem.


49



move it out, commit, then move it back in. This has worked for me in the past. There is probably a 'gittier' way to accomplish this.


42



What didn't work for me

(Under Linux), I wanted to use the posts here suggesting the ls-files --ignored --exclude-standard | xargs git rm -r --cached approach. However, (some of) the files to be removed had an embedded newline/LF/\n in their names. Neither of the solutions:

git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

cope with this situation (get errors about files not found).

So I offer

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached

This uses the -z argument to ls-files, and the -0 argument to xargs to cater safely/correctly for "nasty" characters in filenames.

In the manual page git-ls-files(1), it states:

When -z option is not used, TAB, LF, and backslash characters in pathnames are represented as \t, \n, and \\, respectively.

so I think my solution is needed if filenames have any of these characters in them.

EDIT: I have been asked to add that --- like any git rm command --- this must be followed by a commit to make the removals permanent, e.g. git commit -am "Remove ignored files".


37



I accomplished this by using git filter-branch. The exact command I used was taken from the man page:

WARNING: this will delete the file from your entire history

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

This command will recreate the entire commit history, executing git rm before each commit and so will get rid of the specified file. Don't forget to back it up before running the command as it will be lost.


33