Как удалить большой файл, ошибочно зафиксированный в git

Возможный дубликат:
Как удалить большой файл из истории коммитов в Git?

Я сделал глупость. Представьте, что я зафиксировал файл размером 100 МБ. Затем я вижу это, удаляю этот файл и снова фиксирую. Это нормальная процедура удаления файла.

Но теперь побочным эффектом является то, что моя история тяжелая, потому что она сохранила этот большой файл (я думаю, поэтому он тяжелый). Я использую только локальный git, поэтому я не синхронизируюсь ни на одном сервере.

Как я могу окончательно удалить этот файл и сэкономить место на диске?


person Rodrigo    schedule 10.11.2011    source источник
comment
См. Принятый ответ на мой вопрос stackoverflow.com/questions/7969831/   -  person Daniel Böhmer    schedule 10.11.2011
comment
Используйте BFG repo-cleaner, более простую и быструю альтернативу git-filter-branch, специально созданную мной для удаления ненужных файлов из истории Git. См. stackoverflow.com/a/17890278/438886   -  person Roberto Tyley    schedule 27.07.2014


Ответы (3)


Вы можете сделать это с помощью команды git filter-branch, например:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD

Дополнительную документацию можно найти здесь http://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository

person Leo    schedule 10.11.2011
comment
Обратите внимание, что он также удалит текущую извлеченную версию, поэтому убедитесь, что у вас есть резервная копия, если вам нужно ее сохранить. - person rleelr; 06.10.2016
comment
Я использую винду. Мне пришлось поменять одинарные кавычки на двойные. - person Colonel Panic; 12.10.2016
comment
@rleelr Я думаю, что страница github дает чистое решение, не затрагивая другие файлы: help.github.com/articles/ - person MeadowMuffins; 29.06.2017
comment
У меня такая ошибка: Cannot rewrite branches: You have unstaged changes. - person capybaralet; 14.10.2017
comment
Я не мастер в git, поэтому, например, я делаю это в ветке, отличной от master. Что происходит с тем же файлом, который существует на главном сервере? Удаляется ли он автоматически из истории мастера или остается нетронутым, пока я не объединяю ветку, в которой я удалил историю, в мастер? - person Souvik Ghosh; 17.10.2017
comment
Если вы запустите это локально, а затем нажмете, это повлияет на удаленный сервер? - person Alexander Mills; 05.07.2018
comment
@AlexanderMills: да, просто не забывайте нажимать, используя --force, например, в git push origin master --force. - person Leo; 06.07.2018
comment
Я не уверен, нужен ли --force - person Alexander Mills; 06.07.2018
comment
Полезно отметить: это выполняется только для каждой ветки и будет значительно ускорено за счет указания диапазона фиксации (например, b42f36Bdc..HEAD), который, как вы знаете, содержит файл. - person Jethro; 19.12.2018
comment
Я заблокировал себя: файл, о котором идет речь, настолько велик, что его не удается отправить, поэтому git push origin master --force обречен, и без него я получаю Cannot rewrite branches: You have unstaged changes в команде filter-branch. Могу ли я удалить еще не отправленную фиксацию, кроме отката? - person Cee McSharpface; 06.08.2019
comment
@dlatikay, если вы еще не отправили коммит, содержащий большой файл, вы можете использовать git rebase --interactive, чтобы полностью удалить этот коммит перед отправкой. - person Leo; 07.08.2019
comment
Чудо-лекарство от mp4, который не хотел уходить. - person mLstudent33; 21.11.2019
comment
1. git filter-branch --tree-filter 'rm -rf path/to/your/file' HEAD 2. ЕСЛИ есть эта ошибка: Невозможно переписать ветки: У вас есть неустановленные изменения. 3. git stash save 4. git push origin master --force - person kn3l; 24.11.2019
comment
Это досадное исправление. Вы получите все коммиты из всего вашего репозитория в запросе на вытягивание. - person coderboi; 29.05.2021
comment
@coderboi Да, вы фактически переписываете всю свою историю, в зависимости от того, когда был добавлен указанный файл. - person Leo; 31.05.2021

Ищете команду filter-branch. Это позволяет вам безвозвратно удалять файлы из списка. В этом блоге есть отличное руководство по удалению проблемных файлов из репозитория.

person JaredPar    schedule 10.11.2011

Вы можете взять этот замечательный сценарий от Дэвида Андерхилла, чтобы удалить файл из репозитория git:

#!/bin/bash
set -o errexit

# Author: David Underhill
# Script to permanently delete files/folders from your git repository.  To use 
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2

if [ $# -eq 0 ]; then
    exit 0
fi

# make sure we're at the root of git repo
if [ ! -d .git ]; then
    echo "Error: must run this script from the root of a git repository"
    exit 1
fi

# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD

# remove the temporary history git-filter-branch otherwise leaves behind for a long time
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune
person topek    schedule 10.11.2011
comment
Будьте осторожны, так как этот скрипт может работать долгое время, если у вас много коммитов, как у меня (~ 30k, и он будет работать весь день). - person Alain P; 09.03.2015
comment
@AlainP, вы должны избавиться от старых коммитов, кому нужно столько (30K)? :) - person Alexander Mills; 06.07.2018