git rm - фатально: pathspec не відповідає жодному файлу


87

Я випадково додав понад 9000 фотографій до папки свого проекту. І скоїв їх. Потім видалив їх з диска. Здійснено.

Тепер я намагаюся внести зміни на сервер git. Але це займає занадто багато часу і намагається надіслати 12 Гб даних.

Я перевірив розмір файлів на диску і бачу, що справді .gitпапка займає 12 Гб.

Як видалити звідти фотографії ? Я спробував git rm, але не вдається:

❯ git rm public/photos
fatal: pathspec 'public/photos' did not match any files

Тому що я їх уже видалив з диска, але вони все ще знаходяться в .gitпапці.

Я намагався додати public/photosдо .gitignore:

public/photos/
*.zip

Але результату немає. Звичайно, я міг hard reset headдо того моменту, коли у мене в проекті не було стільки сміттєвих фотографій. Але з того часу я робив багато разів і вносив багато змін в код.

Відповіді:


86

У вашому випадку використовуйте git filter-branchзамість git rm.

git rm буде видаляти файли в тому сенсі, що вони більше не будуть відстежуватися git, але це не видаляє старі об'єкти комітів, що відповідають цим зображенням, і тому ви все одно будете застрягати при натисканні на попередні коміти, що відповідають 12 ГБ зображень.

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

  1. Використовуйте команду

    git filter-branch --force --index-filter \
      'git rm -r --cached --ignore-unmatch public/photos' \
      --prune-empty --tag-name-filter cat -- --all
    
  2. Після завершення гілки фільтра переконайтеся, що жоден ненавмисний файл не був втрачений.

  3. Тепер додайте правило .gitignore

    echo public/photos >> .gitignore
    git add .gitignore && git commit -m "ignore rule for photos"
    
  4. Тепер зробіть поштовх

    git push -f origin branch
    

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

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


2
Гей, у мене така ж проблема, але при введенні команди на кроці 1 я отримую помилку: fatal: bad revision '--prune-empty'. Будь-яка підказка?
kevin

@kevin вибачте, пропустив цей коментар. Ви можете запустити його без цього прапора. Обрізання видалило б будь-який порожній об’єкт коміту.
вт 無

1
Якщо не ця лінія git add .gitignore && commit -m "ignore rule for photos"будеgit add .gitignore && git commit -m "ignore rule for photos"
Clone

@Clone так, мав це бути, виправив це зараз :)
mu 無

1
Це шалено дивовижна відповідь. Виправлена ​​проблема, з якою я стикався з моїм репо вже кілька років. Дякую!
Моше

18

Дуже проста відповідь.

Крок 1:

Спочатку додайте свої файли, які не відстежуються, до яких ви хочете видалити:

використовуючи git add .або git add <filename>.

Крок 2:

Потім видаліть їх легко , використовуючи команду git rm -f <filename>тут ГТ = видалити і -f = forcely.


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

9

Крок 1

Додайте до файлу імена .gitignoreфайлів.

Крок 2

git filter-branch --force --index-filter \
    'git rm -r --cached --ignore-unmatch YOURFILE' \
    --prune-empty --tag-name-filter cat -- --all

Крок 3

git push -f origin branch

Велике спасибі @mu.


7
... я завжди думав, що git складніше, ніж це повинно бути, це підтверджує. Ніхто не може навіть згадати існування більшості команд git, не кажучи вже про їхні прапори та химерності. Модель Git має сенс, і вона працює, поки ви не будете слідувати простому потоку, і як тільки ви застрягнете, ви застрягнете важко.
Мухаммед Умер,

2
Це рішення працює для мене, мені потрібно було--ignore-unmatch
гухур,


1

Це ланцюги працюють у моєму випадку:

  1. git rm -r WebApplication/packages

Був підтверджений git-діалог. Вам слід вибрати варіант "y".

  1. git commit -m "blabla"
  2. git push -f origin <ur_branch>

0
git stash 

зробив роботу, він відновив файли, які я видалив, використовуючи rmзамість них git rm.

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


0

Для видалення відстежуваного та старого комітованого файлу з git ви можете скористатися наведеною нижче командою. Тут у моєму випадку я хочу відстежити та видалити весь файл із distкаталогу.

git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch dist' --tag-name-filter cat -- --all

Потім вам потрібно додати його до свого, .gitignoreщоб він не відстежувався далі.


-1

У мене був повторюваний каталог (~ web / web), і він видалив вкладений дублікат, коли я працював rm -rf webу першій веб-папці.


Вибачте! Напевно, я неправильно прочитав питання. Я думав, що це і було метою
ccsinsf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.