Удалить файлы из gitignore
В рамках данного урока рассмотрим вопросы, касающиеся добавления, удаления и переименования файлов в 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? :)
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.
I did a very straightforward solution by manipulating the output of the .gitignore statement with sed:
- print the .gitignore file
- remove all comments from the print
- delete all empty lines
- add 'git rm -r ' to the start of the line
- execute every line.
" 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 вам менять и не потребуется.
Итоги
Надеюсь, мой материал поможет вам в безопасной работе с конфиденциальными данными.
А вам случалось отправлять в общедоступный репозиторий что-то такое, что туда попадать не должно?
Читайте также: