Видаліть каталог із віддаленого сховища після додавання їх у .gitignore


597

Я вчинив і пересунув деякий каталог до github. Після цього я змінив .gitignoreфайл, додавши каталог, який слід ігнорувати. Все працює добре, але каталог (зараз ігнорується) залишається на github.

Як видалити цей каталог з github та історії сховища?


Відповіді:


1065

Правила у вашому .gitignoreфайлі застосовуються лише до файлів, що не відслідковуються. Оскільки файли в цьому каталозі вже були зафіксовані у вашому сховищі, вам потрібно видалити їх, створити фіксацію та натиснути на GitHub:

git rm -r --cached some-directory
git commit -m 'Remove the now ignored directory "some-directory"'
git push origin master

Ви не можете видалити файл із своєї історії, не переписавши історію вашого сховища - цього не слід робити, якщо хтось інший працює з вашим сховищем або ви використовуєте його з декількох комп'ютерів. Якщо ви все ще хочете це зробити, ви можете скористатися git filter-branchдля того, щоб переписати історію - тут є корисний посібник .

Крім того, зауважте, що вихід з git rm -r --cached some-directoryбуде мати щось на зразок:

rm 'some-directory/product/cache/1/small_image/130x130/small_image.jpg'
rm 'some-directory/product/cache/1/small_image/135x/small_image.jpg'
rm 'some-directory/.htaccess'
rm 'some-directory/logo.jpg'

rmЗворотній зв'язок від мерзотника про сховище; файли все ще знаходяться в робочому каталозі.


3
Якщо хтось інший витягне, чи будуть ігноровані тепер файли для них видалені або залишиться недоторканим?
Мартін Конічек

3
@Martin Konicek: якщо користувач, який перетягує ці зміни, не змінює ці файли, вони будуть видалені.
Марк Лонгейр

@MarkLongair Що робить -rі що --cached. Дякую.
Лабаніно

12
@Labanino: -rозначає рекурсивний, необхідний, якщо ви робите цілі каталоги. --cachedпереосмислює нормальну поведінку git щодо їх видалення з робочого каталогу та постановки на видалення для здійснення, і змушує git працювати лише на сценічній ділянці, готовій до здійснення. Це те, як ви говорите git, що хочете зберегти локальну копію файлів.
entheh

2
Це добре працює, але я повинен був спочатку зробити: git reset name_of_fileдля того, що описано вище, щоб працювати
Едвард Хагланд

248

Я роблю це:

git rm --cached `git ls-files -i --exclude-from=.gitignore` 
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

Це дозволить видалити всі файли / папки, які знаходяться у вашому git ігнорувати, заощаджуючи їх, потрібно вибрати їх вручну


Здається, це перестало працювати на мене, я зараз:

 git rm -r --cached . 
 git add .
 git commit -m 'Removed all files that are in the .gitignore' 
 git push origin master

4
Дякую, це мені дуже допомогло! Якщо ви використовуєте windows powerhell, можете зробити цеforeach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
Матвій

10
Спробував ваш другий підхід, він видалив усі файли з мого локального git!
artnikpro

2
Я думаю, ти повинен перейти до підкаталогу і зробити це. Виправте мене, якщо я помиляюся.

То чого ми сьогодні дізналися, діти? "Не запускайте випадковий код, який ви знайдете в" Переповнення стека! "
Джонатан Ландрум

49

Відповідно до мого відповіді тут: Як видалити каталог із сховища git?

Щоб видалити папку / каталог тільки з сховища git, а не з локального, спробуйте 3 прості дії.


Кроки для видалення каталогу

git rm -r --cached FolderName
git commit -m "Removed folder from repository"
git push origin master

Крок ігнорувати цю папку в наступних вчинках

Щоб ігнорувати цю папку з наступних комісій, зробіть один файл у корені з іменем .gitignore та вставте ім'я цієї папки в нього. Ви можете покласти скільки завгодно

Файл .gitignore буде виглядати приблизно так

/FolderName

видалити каталог


1
Це саме те, що я шукав. Дякую :)
Rohit Singh

Я радий, що це допомогло @Rohit Singh
eirenaios

9

Перша відповідь Блонделла не спрацювала для мене. Однак це показало мені правильний шлях. Я зробив те саме, що і це:

> for i in `git ls-files -i --exclude-from=.gitignore`; do git rm --cached $i; done
> git commit -m 'Removed all files that are in the .gitignore'
> git push origin master

Раджу перевірити файли, які потрібно видалити спочатку, виконавши наведене нижче твердження:

git ls-files -i --exclude-from=.gitignore

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


5

Примітка. Це рішення працює лише з графічним інтерфейсом Github Desktop .

Використовуючи графічний інтерфейс Github Desktop це дуже просто.

  1. Перемістіть папку в інше місце (до папки проекту) тимчасово.

  2. Відредагуйте .gitignoreфайл та видаліть запис папки, який би видалив головне сховище на сторінці github.

  3. Введіть і синхронізуйте папку проекту.

  4. Повторно перемістіть папку в папку проекту

  5. Повторно редагуйте .gitignoreфайл.

Це все.


5

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

git ls-files -i --exclude-from=.gitignore > to_remove.txt
while read line; do `git rm -r --cached "$line"`; done < to_remove.txt
rm to_remove.txt
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

4

Цей метод застосовує стандартну поведінку .gitignore і не вимагає вручну вказувати файли, які потрібно ігнорувати .

Більше не можна використовувати --exclude-from=.gitignore: / - Ось оновлений метод:

Загальна порада: почніть з чистого репо-репортажу - все, що зроблено, нічого не очікує на робочий каталог чи індекс, і зробіть резервну копію !

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

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


0

Якщо ви працюєте з PowerShell, спробуйте наступне як одну команду.

PS MyRepo> git filter-branch --force --index-filter
>> "git rm --cached --ignore-unmatch -r .\\\path\\\to\\\directory"
>> --prune-empty --tag-name-filter cat -- --all

Тоді git push --force --all.

Документація: https://git-scm.com/docs/git-filter-branch


Як використання git filter-branchвідрізняється від використання git rm? Я спочатку думав, що я повинен використовувати версію, git filter-branchале більшість коментарів тут рекомендують використовувати git rm. З того, що я розумію, git rmвидаляє його лише з поточного робочого каталогу та індексу. Але якщо до цього додано кілька комісій раніше, він все одно буде знаходитися у сховищі.
alpha_989

Правильно. git rmвидалить файл із останньої комісії в майбутньому. git filter-branchдозволяє нам видалити його з усієї історії. Дивіться також: help.github.com/articles/…
Shaun Luttin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.