Як видалити файли, перелічені в .gitignore, але все ще знаходяться у сховищі?


327

У моєму сховищі є деякі файли, які слід ігнорувати, я додав їх до .gitignore, але, звичайно, вони не видаляються з мого сховища.

Отже, моє запитання: чи є магічна команда чи скрипт за допомогою фільтр-гілки, який може переписати мою історію та легко видалити всі ці файли? Або просто команда, яка створить команду, яка видалить їх?





ПОПЕРЕДЖЕННЯ. Хоча цей фізичний файл не видалить з вашого локального, він видалить файли з інших машин розробників при наступному натисканні git. Як змусити Git "забути" про файл, який відслідковувався, але зараз він знаходиться у .gitignore?
— Kris Roofe

@Stevoisiak це не дублікат цього питання, оскільки цей запитує про ВСІ ігноровані файли, і він також має кращу відповідь, ніж будь-який із подібних питань.
— Омн

Відповіді:


438

Ви можете видалити їх із сховища вручну:

git rm --cached file1 file2 dir/file3

Або якщо у вас багато файлів:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

Але це, здається, не працює в Git Bash для Windows. Він видає повідомлення про помилку. Наступне працює краще:

git ls-files -i --exclude-from=.gitignore | xargs git rm --cached  

Щодо переписування всієї історії без цих файлів, я дуже сумніваюся, що існує автоматичний спосіб це зробити.
І всі ми знаємо, що переписувати історію погано, чи не так? :)


2
На жаль, команда Git Bash для Windows не працює зі шляхами, які містять пробіли
— Нейт Банді,

19
@Cupcake спасибі git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cachedяк здається, робить трюк
— Нейт Банді

3
Я застряг з тією ж проблемою на вікнах. Я використовую powershell, і в моєму випадку я отримав третю команду, яку підказав @ samy-dindane і змінив її на передбачення. Це стало такимgit ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
— digaomatias

1
"git ls-files -i --exclude-from = .gitignore" дуже корисний, він повідомляє мені, які файли виключаються .ignore.
— Оуен Цао

1
Я був радий знайти ці команди, АЛЕ це насправді не видаляє файли з сховища. Коли я видалив 2300 кБ зображень, розмір сховища зменшився лише на 10 кБ. Тому його не можна використовувати, наприклад, для зменшення сховища та швидшого перенесення.
— Ян Потужник

343

Простіший спосіб роботи на будь-якій ОС - це зробити

git rm -r --cached .
git add .
git commit -m "Removing all files in .gitignore"

Ви в основному читаєте всі файли, крім тих, що в .gitignore


1
Як цей ефект інших користувачів на репо , яка виконує тягнути - як я прочитав це папка ми не хочемо , щоб відстежувати більше віддаляється ??? Як ми можемо запобігти цьому - ми просто хочемо відстебнути
— snh_nl

Це позначить усі файли як змінені підробленим повідомленням про фіксацію!
— Гайдар Зейнеддін

3
що ти маєш на увазі підроблене повідомлення про вчинення? Це справжнє повідомлення про прихильність: P Ви можете змінити повідомлення звичайно, залежно від ваших потреб ...
— gtatr

1
Просто для повноти вам потрібна команда git push в кінці.
— Mariusz Bialobrzeski

1
Не робіть цього, це видалить історію з усіх файлів
— agrath

144

Оскільки файли в .gitignore не відслідковуються, ви можете використовувати команду git clean для рекурсивного видалення файлів, які не перебувають під контролем версій.

Використовуйте git clean -xdnдля виконання сухого пробігу і дивіться, що буде видалено.
Потім використовуйте git clean -xdfдля його виконання.

В основному, git clean -hабо man git-clean(в unix) допоможе вам.

Майте на увазі, що ця команда також видалить нові файли , які не знаходяться в області постановки.

Сподіваюся, це допомагає.


6
Це має бути прийнятою відповіддю. Це насправді працює (прийнята відповідь не працювала для мене на macOS), і вона чистіша.
— Роджер Оба

25
Ця відповідь не застосовується - ОП говорить, що файли в .gitignore них відслідковуються.
— Кен Вільямс

20
ПОДЕРЖАЙТЕ! Це назавжди видаляє всі незаймані файли, а не просто видалення з гілки
— Еммануель

1
git clean -xdnсухий прогін , який не буде видаляти. наступний буде.
— JohnZaj

17
-1: Це дуже хибна відповідь - оригінальний плакат хотів видалити з сховища, а не видалити файли повністю. Я був таким близьким до видалення завантаження динамічних файлів, необхідних моїм IDE, але не вимагати того, щоб бути в репо.
— Auspice

4

Я зробив дуже просте рішення, маніпулюючи висновком оператора .gitignore за допомогою sed:

cat .gitignore | sed '/^#.*/ d' | sed '/^\s*$/ d' | sed 's/^/git rm -r /' | bash

Пояснення:

  1. надрукувати файл .gitignore
  2. видалити всі коментарі з друку
  3. видалити всі порожні рядки
  4. додати "git rm -r" до початку рядка
  5. виконати кожен рядок.


0

У Linux можна використовувати цю команду:

для прикладу я хочу видалити "* .py ~", тому моя команда повинна бути ==>

find . -name "*.py~" -exec rm -f {} \;


-3

Після додавання його до .gitignore git ігнорує відповідні файли .gitignore.

Але файли, які вже існували в сховищі, все ще будуть в.

використовувати git rm files_ignored; git commit -m 'rm no use files'для видалення ігнорованих файлів.


4
Їх дуже багато, чи є спосіб видалити їх, не вказуючи їх імена?
— Intrepidd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.