Удалить файл из репозитория Git (история)



(решено, см. Нижнюю часть тела вопроса)

Глядя на это уже давно, то, что у меня есть до сих пор:




в значительной степени тот же метод, но оба они оставляют объекты в пакетных файлах... Застрявший.

Что я пробовал:



git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name'
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc


еще файлы в пакете, и вот как я это знаю:



git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3


и так:



git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune


то же самое...



пробовал git clone трюк, он удалил некоторые файлы (~3000 из них), но большие файлы все еще там...



у меня есть несколько больших устаревших файлов в репозитории, ~200 м, и я действительно не хочу их там... И я не хочу сбрасывать репозиторий до 0 : (



решение:
Это самый короткий способ избавиться от файлы:




  1. проверка .git / packed-refs-моя проблема была в том, что у меня там было refs/remotes/origin/master строка для удаленного репозитория, удалите его, иначе git не удалит эти файлы


  2. (необязательный)git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 - чтобы проверить наличие самых больших файлов


  3. (необязательный)git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98 - чтобы проверить, что это за файлы


  4. git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' - чтобы удалить файл из всех редакций


  5. rm -rf .git/refs/original/ - чтобы удалить git резервное копирование


  6. git reflog expire --all --expire='0 days' - удалить все свободные объекты


  7. git fsck --full --unreachable - чтобы проверить, есть ли какие-либо свободные объекты


  8. git repack -A -d - переупаковка


  9. git prune - чтобы окончательно удалить эти объекты

722   8  

8 ответов:

я не могу сказать наверняка без доступа к данным вашего репозитория, но я считаю, что, вероятно, есть один или несколько упакованных ссылок, которые все еще ссылаются на старые коммиты до того, как вы запустили git filter-branch. Это объясняет, почему git fsck --full --unreachable не вызывает большой двоичный объект недоступный объект, даже если у вас истек срок действия вашего reflog и удалил оригинал (без упаковки) РЭС.

вот что я бы сделал (после git filter-branch и git gc было сделано):

1) Убедитесь, что оригинальные ссылки ушел:

rm -rf .git/refs/original

2) удалить все записи reflog:

git reflog expire --all --expire='0 days'

3) Проверьте старые упакованные ссылки

это может быть сложно, в зависимости от того, сколько упакованных ссылок у вас есть. Я не знаю никаких команд Git, которые автоматизируют это, поэтому я думаю, что вам придется сделать это вручную. Сделайте резервную копию .git/packed-refs. Теперь редактировать .git/packed-refs. Проверьте старые ссылки (в частности, посмотреть, если он упакован любые ссылки от .git/refs/original). Если вы найдете какие-либо старые, которые не должны быть там, удалите их (удалите строку для этой ссылки).

после того, как вы закончите уборку , если git fsck уведомления "недоступные" объекты:

git fsck --full --unreachable

если бы это сработало, и git fsck теперь сообщает Ваш большой blob как недостижимый, вы можете перейти к следующему шагу.

4) переупакуйте ваш упакованный архив(ы)

git repack -A -d

это гарантирует, что недостижимые объекты будут распакованы и остаться распаковывается.

5) обрезать свободные (недостижимые) объекты

git prune

и это должно сделать это. Git действительно должен иметь лучший способ управлять упакованными refs. Может быть, есть лучший способ, о котором я не знаю. При отсутствии лучшего способа, ручное редактирование packed-refs файл может быть единственный способ уйти.

Я бы рекомендовал использовать BFG Repo-Cleaner, более простая и быстрая альтернатива git-filter-branch специально разработан для перезаписи файлов из истории Git. Один из способов, которым это делает вашу жизнь проще здесь является то, что он на самом деле обрабатывает все ссылки по умолчанию (все теги, ветви, такие как refs / remotes / origin / master и т. д.), Но это также 10-50x быстрее.

вы должны тщательно следовать этим шагам здесь: http://rtyley.github.com/bfg-repo-cleaner/#usage - но основной бит таков: загрузите банка БДВ (требуется Java 6 или выше) и выполните следующую команду:

$ java -jar bfg.jar  --delete-files file_name  my-repo.git

любой файл с именем file_name (это не в ваш последний фиксация) будет полностью удалены из истории вашего хранилища. Затем вы можете использовать git gc чтобы убрать мертвые данные:

$ git gc --prune=now --aggressive

BFG, как правило, гораздо проще в использовании чем git-filter-branch - варианты с учетом этих двух общих случаев использования:

  • удаление Сумасшедшие Большие Файлы
  • удаление Пароли, Учетные Данные и другие личные данные

полное раскрытие информации: я автор BFG Repo-Cleaner.

Я обнаружил, что это очень полезно в отношении удаления целой папки, поскольку вышеизложенное мне не очень помогло:https://help.github.com/articles/remove-sensitive-data.

Я:

git filter-branch -f --force \
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \
--prune-empty --tag-name-filter cat -- --all

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

Я пытался избавиться от большого файла в истории, и ответы выше работал, до определенного момента. Смысл в том, что они не работают, если у вас есть теги. Если фиксация, содержащая большой файл, доступна из тега, то вам нужно будет настроить команду filter-branches следующим образом:

git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags

посмотреть: Как удалить конфиденциальные файлы из истории git

выше будет выполнена, если файл не существует в ред. в этом случае '--игнорировать-разъединить выключатель будет исправить это:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD

затем, чтобы получить все свободные объекты из repostiry:

git gc --prune='0 days ago'

у вас есть различные причины для все еще большого размера РЕПО git после git gc, Так как это не удаляет все свободные объекты.

я подробно эти причины в "уменьшить размер репозитория git"

но один трюк, чтобы проверить в вашем случае будет клон ваш "очищенный" git repo и посмотреть, если клон имеет соответствующий размер.

("очищенное" РЕПО " является тем, где вы применили filter-branch, а потом gc и prune)

Это должно быть покрыто git obliterate команда в Git Extras (https://github.com/visionmedia/git-extras).

git obliterate <filename>

у меня была такая же проблема и я нашел отличный учебник на GitHub, которые объясняют шаг за шагом как избавиться от файлов, которые вы совершено случайно.

вот небольшое резюме процедуры, как кекс предложил.

Если у вас есть файл с именем file_to_remove удалить из истории :

cd path_to_parent_dir

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

Comments

    Ничего не найдено.