Удалить файлы из gitignore

Обновлено: 05.07.2024

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

Добавление файлов в git репозиторий

Создайте в каталоге файл README.md любым удобным для вас способом, мы сделаем это с помощью команды touch .

Теперь проверим состояние отслеживаемой директории.

Как вы можете видеть: в рабочей директории есть один неотслеживаемый файл README.md . Git нам подсказывает, что нужно сделать для того, чтобы начать отслеживать изменения в файле README.md : необходимо выполнить команду git add , сделаем это.

Посмотрим ещё раз на состояние.

Видно, что информация о появлении нового файла попала в stage . Для того чтобы это изменение зафиксировалось в репозитории необходимо выполнить команду git commit .

Теперь в рабочей директории и в stage нет объектов, информацию об изменении которых необходимо внести в репозиторий.

В репозиторий был сделан один коммит.

Удаление файлов из git репозитория и из stage

Удаление файла из stage

Вначале разберемся со stage . Создадим ещё один файл.

Внесем изменения в README.md .

Информацию об этом также отправим в stage .

Посмотрим на состояние stage .

Теперь посмотрим на состояние рабочей директории и stage .

Удаление файлов из git репозитория

Удалим файл main.c из рабочей директории.

Уведомим об этом систему git .

Теперь в репозитории остался только один файл README.md .

Удалим файл из репозитория.

Файла main.c больше нет в репозитории.

Его также нет и в рабочем каталоге.

Удалите файл README.md из репозитория самостоятельно.

Переименование файлов в git репозитории

Первый способ. Создадим файл test_main_file.c и добавим его в репозиторий.

Содержимое репозитория после этого будет выглядеть так.

Переименуем его на test_main.c .

Сделаем это в рабочей директории.

Теперь отправим изменение в репозиторий.

В репозитории и в рабочей директории будет находится только файл test_main.c .

Второй способ.

В рамках второго способа рассмотрим работу с командой git mv . Переименуем файл test_main.c в main.c . Текущее содержимое репозитория и рабочего каталога.

Переименуем файл test_main.c на main.c средствами git .

Имя файла изменилось как в репозитории так и в рабочем каталоге.

I have some files in my repository that should be ignored, i added them to the .gitignore but, of course, they are not removed from my repository.

So my question is, is there a magic command or script using filter-branch that can rewrite my history and remove all these files easily? Or simply a command that will create a commit that will remove them ?

171k 44 44 gold badges 318 318 silver badges 483 483 bronze badges 17.4k 5 5 gold badges 51 51 silver badges 63 63 bronze badges WARNING: While this will not remove the physical file from your local, it will remove the files from other developers machines on next git pull. How to make Git “forget” about a file that was tracked but is now in .gitignore? @Stevoisiak this is not a duplicate of that question because this one asks about ALL ignored files and it also has a better answer than any of the similar questions.

9 Answers 9

You can remove them from the repository manually:

Or, if you have a lot of files:

But this doesn't seem to work in Git Bash on Windows. It produces an error message. The following works better:

In PowerShell on Windows this works even better (handles spaces in path and filenames):

Regarding rewriting the whole history without these files, I highly doubt there's an automatic way to do it.
And we all know that rewriting the history is bad, don't we? :)


732 1 1 gold badge 10 10 silver badges 24 24 bronze badges 16.2k 3 3 gold badges 38 38 silver badges 49 49 bronze badges "git ls-files -i --exclude-from=.gitignore" is very helpful, it tells me what files are excluded by .ignore. I was happy to find these commands, BUT it does not really remove the files from repository. When i removed 2300 kB of images, repository size dropped only 10 kB. So it cannot be used, for example, to make repository smaller and faster to transfer.

An easier way that works regardless of the OS is to do

You basically remove and re-add all files, but git add will ignore the ones in .gitignore .

Using the --cached option will keep files in your filesystem, so you won't be removing files from your disk.

Note: Some pointed out in the comments that you will lose the history of all your files. I tested this with git 2.27.0 on MacOS and it is not the case. If you want to check what is happening, check your git diff HEAD

1 before you push your commit.

5,533 1 1 gold badge 15 15 silver badges 26 26 bronze badges How does this effect other users on the repo executing a pull - as I read it the folder we dont want to track anymore is deleted. How can we prevent this - we just want to untrack Just for a completeness sake you need git push command at the end. Just to clarify a bit because the git status after doing git rm -r --cached . git add . can look a bit scary: These three commands that @gtatr provides essentially delete files from git that were previously tracked, but have since been added to your .gitignore file. When I first ran this, I saw a bunch of files and freaked out for a second but upon further inspection I noticed they were all files that were listed in my .gitignore file.

As the files in .gitignore are not being tracked, you can use the git clean command to recursively remove files that are not under version control.

Use git clean -xdn to perform a dry run and see what will be removed.
Then use git clean -xdf to execute it.

Basically, git clean -h or man git-clean (in unix) will give you help.

Be aware that this command will also remove new files that are not in the staging area.


2,427 1 1 gold badge 10 10 silver badges 5 5 bronze badges BEWARE! This permanently deletes all untracked files, rather than just removing from the branch -1: This is a highly misleading answer - the original poster wanted to remove from the repository, not remove the files completely. I was this close to deleting a load of dynamic files required by my IDE but not required to be in the repo.

I did a very straightforward solution by manipulating the output of the .gitignore statement with sed:

  1. print the .gitignore file
  2. remove all comments from the print
  3. delete all empty lines
  4. add 'git rm -r ' to the start of the line
  5. execute every line.


+1 for scripting and explaining it. Explaining the danger of running it right into bash without review may have been an oversight.

" git clean " (man) and git ls-files -i (man) had confusion around working on or showing ignored paths inside an ignored directory, which has been corrected with Git 2.32 (Q2 2021).

That means the 2021 version of the accepted answer would be:

ls-files : error out on -i unless -o or -c are specified

Signed-off-by: Elijah Newren

ls-files --ignored (man) can be used together with either --others or --cached .

After being perplexed for a bit and digging in to the code, I assumed that ls-files -i was just broken and not printing anything and I had a nice patch ready to submit when I finally realized that -i can be used with --cached to find tracked ignores.

While that was a mistake on my part, and a careful reading of the documentation could have made this more clear, I suspect this is an error others are likely to make as well.
In fact, of two uses in our testsuite, I believe one of the two did make this error.
In t1306.13, there are NO tracked files, and all the excludes built up and used in that test and in previous tests thus have to be about untracked files.
However, since they were looking for an empty result, the mistake went unnoticed as their erroneous command also just happened to give an empty answer.

-i will most the time be used with -o , which would suggest we could just make -i imply -o in the absence of either a -o or -c , but that would be a backward incompatible break.
Instead, let's just flag -i without either a -o or -c as an error, and update the two relevant testcases to specify their intent.

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

Файл .gitignore указывает, какие неотслеживаемые файлы Git должен игнорировать.

Какие файлы следует игнорировать?

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

  • Файлы времени выполнения, такие как файлы журнала, блокировки, кеша или временные файлы.
  • Файлы с конфиденциальной информацией, такой как пароли или ключи API.
  • Скомпилированный код, например .class или .o .
  • /node_modules зависимостей, например /vendor или /node_modules .
  • Каталоги сборки, например /public , /out или /dist .
  • Системные файлы, такие как .DS_Store или Thumbs.db
  • Файлы конфигурации IDE или текстового редактора .

.gitignore Шаблоны

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

Комментарии

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

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

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

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

Буквальные имена файлов

Шаблон Примеры совпадений
/access.log access.log
access.log access.log
logs/access.log
var/logs/access.log
build/ build

Подстановочные символы

Шаблон Примеры совпадений
*.log error.log
logs/debug.log
build/logs/error.log

Шаблон Примеры совпадений
logs/** Соответствует чему-либо в каталоге logs .
**/build var/build
pub/build
build
foo/**/bar foo/bar
foo/a/bar
foo/a/b/c/bar

Шаблон Примеры совпадений
access?.log access0.log
access1.log
accessA.log
foo?? fooab
foo23
foo0s

Квадратных скобок

Шаблон Примеры совпадений
*.[oa] file.o
file.a
*.[!oa] file.s
file.1
file.0
access.2.log access.0.log
access.1.log
access.2.log
file.[ac].out file.a.out
file.b.out
file.c.out
file.[a-cx-z].out file.a.out
file.b.out
file.c.out
file.x.out
file.y.out
file.z.out
access.[!0-2].log access.3.log
access.4.log
access.Q.log

Отрицательные паттерны

Шаблон, который начинается с восклицательного знака ( ! ), Отменяет (повторно включает) любой файл, который игнорируется предыдущим шаблоном. Исключением из этого правила является повторное включение файла, если его родительский каталог исключен.

Шаблон Примеры совпадений
*.log
!error.log
error.log или logs/error.log не будут проигнорированы

.gitignore Пример

Ниже приведен пример того, как может выглядеть ваш файл .gitignore :

Местный .gitignore

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

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

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

Личные правила игнорирования

Шаблоны, специфичные для вашего локального репозитория и не подлежащие распространению в другие репозитории, должны быть установлены в файле .git/info/exclude .

Например, вы можете использовать этот файл, чтобы игнорировать файлы, сгенерированные из ваших личных инструментов проекта.

Глобальный .gitignore

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

Файл можно назвать как угодно и хранить в любом месте. Чаще всего этот файл хранится в домашнем каталоге. Вам придется вручную создать файл и настроить Git для его использования.

Например, чтобы установить

/.gitignore_global в качестве глобального файла игнорирования Git, вы должны сделать следующее:

Добавьте файл в конфигурацию Git:

Откройте файл в текстовом редакторе и добавьте в него свои правила.

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

Игнорирование ранее зафиксированных файлов

Файлы в вашей рабочей копии можно отслеживать или нет.

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

Параметр --cached указывает git не удалять файл из рабочего дерева, а только удалять его из индекса.

Чтобы рекурсивно удалить каталог, используйте параметр -r :

Если вы хотите удалить файл и из индекса, и из локальной файловой системы, опустите параметр --cached .

При рекурсивном удалении файлов используйте параметр -n , который выполнит «пробный запуск» и покажет вам, какие файлы будут удалены:

Отладка файла .gitignore

Иногда бывает сложно определить, почему игнорируется конкретный файл, особенно когда вы используете несколько файлов .gitignore или сложные шаблоны. Здесь пригодится команда git check-ignore с параметром -v , которая сообщает git отображать сведения о соответствующем шаблоне.

Например, чтобы проверить, почему файл www/yarn.lock игнорируется, вы должны запустить:

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

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

Отображение всех игнорируемых файлов

Команда git status с параметром --ignored отображает список всех игнорируемых файлов:

Выводы

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

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.



Удаление файлов с конфиденциальной информацией из Git-репозитория ( изображение большого размера )

Минимизация ущерба

Итак, вы случайно закоммитили файл с конфиденциальной информацией. Назовём этот файл .env . Сразу после того, как это случилось, надо задать себе пару вопросов:

  • Отправлен ли коммит в удалённый репозиторий?
  • Является ли удалённый репозиторий общедоступным?

▍Коммит пока не отправлен в удалённый репозиторий


Файлы останутся в рабочей копии репозитория, вы сможете внести в проект необходимые изменения.

Если же вы хотите сохранить коммит и вам нужно просто удалить из него определённые файлы, тогда поступите так:


Параметр --amend можно использовать только для работы с самым свежим коммитом. Если вы, после неудачного коммита, добавили ещё несколько, воспользуйтесь такой командой:

▍Коммит отправлен в удалённый репозиторий

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

Если ваш репозиторий является приватным, и при этом он не доступен ботам или людям, которым вы не доверяете, вы можете просто внести поправки в последний коммит, воспользовавшись парой вышеприведённых команд.

Если вы отправили в репозиторий, после проблемного коммита, и другие коммиты, это не помешает вам убрать файлы с конфиденциальными данными из истории Git, воспользовавшись командой git filter-branch или инструментом BFG Repo-Cleaner.

Вот пример использования git filter-branch :


Но, делая это, учитывайте два важных аспекта подобных изменений, вносимых в репозиторий:

  • Вы меняете историю Git. Если на текущее состояние репозитория полагаются другие люди, если от этого состояния зависят какие-то ветки того же репозитория, его форки, открытые PR, то это нарушит их работу. В подобных случаях относитесь к репозиторию как к общедоступному и постарайтесь не вносить изменения в его историю.
  • Вам нужно будет очистить кеш. Вам понадобится обратиться в службу поддержки платформы, на которой хранится ваш репозиторий, и попросить очистить его кеш. Несмотря на то, что вы исправили проблемный коммит или переписали историю репозитория, старый коммит, содержащий конфиденциальные данные, останется в кеше. Для того чтобы к нему обратиться, нужно будет знать его ID, но к нему можно будет получить доступ до тех пор, пока кеш не очистят.

Нужно ли создавать новые секретные ключи в том случае, если их актуальные версии попали в публичный репозиторий?

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

Даже если вы удалили эти данные из репозитория, вы ничего не сможете сделать с ботами и с форками репозитория. Как же поступить?

  • Деактивируйте все ключи или пароли. Это надо сделать в первую очередь. После того, как вы деактивируете ключи, конфиденциальные сведения, ушедшие в общий доступ, оказываются бесполезными.
  • Настройте файл .gitignore . Сделайте в .gitignore записи о файлах с конфиденциальной информацией для того чтобы Git не отслеживал бы состояние этих файлов.
  • Подготовьте коммит, в котором нет файлов с конфиденциальной информацией.
  • Отправьте изменения в репозиторий, снабдите коммит пояснениями о возникшей ситуации. Не пытайтесь скрыть ошибку. Все программисты, работающие над проектом, включая вас, по достоинству оценят наличие в репозитории коммита с разъяснениями ситуации и с описанием того, что именно было исправлено с помощью данного коммита.

Рекомендации по хранению конфиденциальных файлов в проектах, в которых для контроля версий применяется Git

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

▍Храните секретные данные в файле .env (или в другом подобном файле)

Ключи к API и другие подобные сведения стоит хранить в единственном файле .env . При таком подходе, если Git не отслеживает состояние файла .env , вы, добавив в этот файл новый ключ, не отправите его случайно в репозиторий.

Ещё одно преимущество такого подхода заключается в том, что так у вас будет доступ ко всем ключам через глобальную переменную process .

▍Используйте, если это возможно, ключи API

Скомпрометированные ключи API легко деактивировать, такие ключи легко создать заново. Если это возможно — используйте именно их, а не нечто вроде логинов и паролей.

▍Храните ключи API, пользуясь средствами вашего инструмента для сборки проектов

Ключи API обычно нужны при сборке приложений. Инструменты для сборки проектов, вроде Netlify, позволяют держать ключи в защищённых хранилищах. Такие ключи автоматически внедряются в приложение с использованием глобальной переменной process .


Управление переменными окружения

▍Добавьте запись о файле .env в файл .gitignore

Сделайте так, чтобы Git не отслеживал бы файлы, содержащие конфиденциальную информацию.

▍Подготовьте шаблонный файл .env.template

Наличие подобного шаблонного файла помогает тем, кто работает над проектом, добавлять в проект ключи API, избавляя их от необходимости чтения документации.

▍Не меняйте историю Git в удалённых репозиториях

Постарайтесь строго придерживаться этого правила. Если вы следовали вышеприведённым рекомендациям, то историю Git вам менять и не потребуется.

Итоги

Надеюсь, мой материал поможет вам в безопасной работе с конфиденциальными данными.

А вам случалось отправлять в общедоступный репозиторий что-то такое, что туда попадать не должно?

Читайте также: