git rm - фатальный: pathspec не соответствует ни одному файлу

87

Я случайно добавил более 9000 фотографий в папку своего проекта. И совершил их. Потом удалил их с диска. Совершено.

Теперь я пытаюсь отправить изменения на git server. Но он занимает слишком много времени и пытается отправить 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
    

Отметьте this , this и this для получения дополнительной помощи. На всякий случай я бы посоветовал вам создать резервную копию репо в вашей системе, прежде чем выполнять эти инструкции.

Что касается вашего исходного сообщения об ошибке, это происходит потому, что вы уже не отслеживали их использование git rm, и, следовательно, git жалуется, потому что не может удалить файл, который не отслеживает. Подробнее об этом читайте здесь .

mu 無
источник
2
Эй, у меня та же проблема, но при вводе команды на шаге 1 я получаю сообщение об ошибке: fatal: bad revision '--prune-empty'. Есть подсказка?
Кевин
@kevin извините, пропустил этот комментарий. Вы можете запустить его без этого флага. При сокращении был бы удален любой пустой объект фиксации.
mu 無
1
Разве эта строчка не git add .gitignore && commit -m "ignore rule for photos"должна бытьgit add .gitignore && git commit -m "ignore rule for photos"
Клон
@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.

klmlfl
источник
7
... я всегда думал, что git сложнее, чем должно быть, это доказывает. Никто не может даже вспомнить о существовании большинства команд git, не говоря уже об их флагах и причудах. Модель Git имеет смысл, и она работает до тех пор, пока вы не будете следовать простому потоку, и как только вы застрянете, вы сильно застрянете.
Мухаммад Умер
2
Это решение, которое работает для меня, мне нужно--ignore-unmatch
гухур
3

использование этого сработало для меня

git rm -f --cached <filename>
Андрея Оливейра
источник
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.

Сначала я проверил последний хэш, но не считаю, что это необходимо.

user1767316
источник
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
источник
Сожалею! Должно быть, я неправильно понял вопрос. Я думал, что цель была именно в этом
ccsinsf