Як видалити файли, перелічені в .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.