Повністю видаліть файли з Git repo та віддаленого на GitHub


78

Я випадково додав папку із зображеннями і скоїв. Потім я зробив ще одне зобов’язання. Потім я видалив ці файли, використовуючи, git rm -f ./imagesі зафіксував знову.

Зараз я зробив набагато більше комітетів у цій галузі (майстер). У моїй ГОЛОВІ у мене немає цієї ./static/imagesпапки.

Завдяки цьому мій розмір репо значно збільшився. Як я можу повністю видалити ці краплі? І я хочу видалити його зі свого віддаленого репозиторію GitHub.


З якоїсь причини вказівки з github та нижче не працювали для мене, але ця відповідь із книги "Pro Git", на яку посилається ця відповідь SO, спрацювала бездоганно: stackoverflow.com/a/16877548/436014 - мені цікаво про різниці між деревним фільтром та індексним фільтром зараз.
waffl

Відповіді:


125

Це те, що ви шукаєте: ігнорування не видаляє файл . Я пропоную вам прочитати цю сторінку, але ось конкретна команда для використання:

git filter-branch --index-filter \
'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

Крім того, щоб видалити всі видалені файли з кешів, які створює git, використовуйте:

rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune

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

Інші посилання з великою кількістю пояснень: Видаліть конфіденційні дані .

[Редагувати] Також див. Це запитання StackOverflow: Видаліть конфіденційні файли та їх коміти з історії Git .

(Команди, скопійовані з natacadoвідповіді користувача на запитання, зв’язане вище.) Якщо ви вже видалили файли з робочої копії, має працювати наступне. Дізнайтеся хеш для коміту, який додав небажані файли. Тоді виконайте:

git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force

1
Ви сказали мені зробити 'git rm --cached <файл>'. Але зараз у мене немає цієї папки "./statis/images", оскільки я маю стільки попереду у проекті. Після цього я зробив багато комітетів.
Абхієет Растогі,

1
@shadyabhi Гм, можливо, спробуйте додати --ignore-unmatch до команди rm. Повідомте мене, якщо це спрацює.
Дархуук,

@Darhuuk Я зробив те, що ти сказав. Отримав багато результатів із вимовою "rm ...". Я зробив $ git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch ./static/images' HEAD, а потім $ rm -rf .git / refs / original / && git reflog expire - -all && git gc --aggressive --prune. Тим не менше мій розмір репо складає 2,7 Мб. Моє джерело - лише 525 КБ. Мої комісії складають лише 118 .. Це досить величезно для менших змін.
Абхієет Растогі,

@shadyabhi Ви пробували рішення в іншому запитанні StackOverflow, яке я зв’язав?
Дархук,

@Darhuuk Чи потрібно мені використовувати rebase? Я лише новачок у всьому цьому, тому я точно не дотримуюся цього.
Абхієет Растогі,

9

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

git rebase -i master

Вам буде представлений список комітетів. Видаліть рядки, у яких є неправдиві коміти, які ви хочете видалити. ("dd" видаляє рядок у vim, редакторі за замовчуванням. Потім збережіть за допомогою ZZ)

Потім звисаючі коміти будуть очищені під час природного збирання сміття git - процес, який ви можете змусити виконати за допомогою команди, даної у відповіді Даргуука.

Редагувати: це буде працювати, навіть якщо ви перейшли у віддалене сховище, але вам доведеться натискати за допомогою --force. (Те саме стосується рішення git filter-branch).

Зверніть увагу, що це буде дуже дратувати кожного, хто витягнув з вашої гілки. Вони повинні проконсультуватися "відновлення після перебазування даних" .


Імовірно, ваше оригінальне випадкове додавання зображень є частиною коміту, який ви хочете зберегти. У цьому випадку вам потрібно відредагувати коміт під час перебазування, щоб розділити частини, які ви хочете зберегти. Ви можете зробити це, замінивши "pick" у списку "rebase -i" для цього коміту на "e" (для редагування). На цьому процес перебазування зупиниться, і ви можете розділити коміт на "git commit --amend".


4

По суті, я повторюю відповідь у поєднанні з цим застереженням щодо форматування Windows , лише щоб він не загубився як коментар.

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

Одна лінія:

git filter-branch --index-filter "git rm -r --cached --ignore-unmatch <file/dir>" HEAD

Кілька рядків:

git filter-branch --index-filter \
    "git rm -r --cached --ignore-unmatch <file/dir>" HEAD
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.