2010-01-29 4 views
70

(решено, см нижней части тела вопроса)
Цели этого в течение длительного времени, что я до сих пор:Удалить файл из репозитория мерзавца (история)

Практически тот же метод, но оба из них оставляют объекты в пакет файлов ... Штука.
Что я пробовал:

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 

То же самое ...

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

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

РЕШЕНИЯ: Это самый короткий путь, чтобы избавиться от файлов:

  1. проверки .git/уплотненных рефы - моя проблема в том, что я был там refs/remotes/origin/master линии для удаленного репозитория удалите его, иначе git не удалит эти файлы
  2. (o ptional)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 - чтобы окончательно удалить эти объекты
+5

Soooo, ваш вопрос ...? – zneak

+0

Возможные дубликаты: http://stackoverflow.com/questions/2100907/how-to-purge-a-huge-file-from-commits-history-in-git/2158271 http://stackoverflow.com/questions/872565/how-do-i-remove-sensitive-files-from-gits-history –

+0

zneak - мой вопрос в заголовке. gbacon - попробовал эти файлы, файлы все еще остаются в файле пакета ... – Devenv

ответ

59

Я не могу сказать наверняка, не имеющему доступ к репозиториям данных, но я считаю, что есть вероятно, один или несколько упакованных ссылок, все еще ссылающихся на старые коммиты, прежде чем вы запустили git filter-branch. Это объясняет, почему git fsck --full --unreachable не вызывает большой blob недостижимым объектом, даже если вы истекли ваш 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. Проверьте старые refs (в частности, проверьте, не упаковали ли они какие-либо из ссылок от .git/refs/original). Если вы найдете старые, которые не должны быть там, удалите их (удалите строку для этого ref).

После завершения очистки файла packed-refs см, если git fsck замечает недостижимые объекты:

git fsck --full --unreachable

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

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

git repack -A -d

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

5) Чернослив рыхлый (недостижимым) объекты

git prune

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

+1

Yey! !! Я люблю тебя ! Проблема была в файле упакованных refs, там были refs/remotes/origin/master со времен, когда я поддерживал его на каком-то сервере ... как только я удалил его, все стало исчезать ... Спасибо! (обновление тела вопроса с полным решением) – Devenv

+0

О, человек, подсказка о упакованных refs была настолько полезна! –

2

См: How do I remove sensitive files from git’s history

выше потерпит неудачу, если файл не существует в оборот.В этом случае, «--ignore-unmatch» переключатель исправить:

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

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

git gc --prune='0 days ago' 
+0

Да, попробовал этот, все еще есть файлы в пакете, и размер не изменился слишком сильно ... – Devenv

+0

Я просто сделал песочницу git и попробовал. Здесь нехорошо. Давайте посмотрим, что я могу понять. –

+0

Получил. См. Отредактированную версию. –

1

У вас есть различные причины для еще большой git репо размер после git gc, т.к. это does not remove all loose objects.

Я подробно эти причины в «reduce the git repository size»

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

(«очистить" репо»является тот, в котором вы сделали применить filter-branch, а затем gc и prune)

+0

Да, протестировал его уже и снова протестировал его, он уменьшил репозиторий на 2k :) и файлы все еще там ... – Devenv

+0

Что странно: 'git count-objects -v -> count: 0, size: 0, in-pack : 10021, пакеты: 1, размер-пакет: 244547, чернослив: 0, мусор: 0' , но: 'git clone test1 test2 -> Проверка файлов: 100% (8509/8509), done' – Devenv

4

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

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

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

Ниже приведено краткое описание процедуры, предложенной Cupcake.

Если у вас есть файл с именем 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 
+0

Ссылка только ответы очень обескуражены в переполнении стека, потому что, если связь разрывается в будущем, тогда ответ становится бесполезным.Пожалуйста, подумайте о суммировании соответствующей информации, содержащейся в ссылке, в вашем ответе. – 2014-04-04 00:05:06

+0

Я обновил свой ответ. Спасибо за совет. –

6

я нашел, что это будет весьма полезно в отношении к удалению всей папки, как указано выше, не реально помочь мне: 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 
7

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

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

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

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

$ git gc --prune=now --aggressive 

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

  • Удаление Сумасшедшие большие файлы
  • Удаление паролей, учетные данные & другие Частные данные

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

+0

Означает ли это также очистку личных данных из удаленных репозиториев после нажатия? –

+0

@ThomasLauria yup, те же очищенные refs выталкиваются в удаленные репозитории при нажатии - инструкции по адресу http://rtyley.github.io/bfg-repo-cleaner/#usage должны его покрывать. Если у вас есть контроль над удаленным репо, вы также можете запустить на нем «git gc --prune = now - aggressive» после нажатия, чтобы сразу же удалить мертвые объекты. –

Смежные вопросы