2010-09-26 9 views
66

Przypadkowo dodałem, zatwierdziłem i zepchnąłem ogromny plik binarny z moim ostatnim commitem do repozytorium Git.Jak usunąć nieużywane obiekty z repozytorium git?

Jak mogę usunąć Git z obiektów, które zostały/zostały utworzone dla tego zatwierdzenia, aby mój katalog .git ponownie się zmniejszył?

Edytuj: Dzięki za twoje odpowiedzi; Próbowałem kilku rozwiązań. Żaden nie działał. Na przykład jeden z GitHub usunięte pliki z historii, ale rozmiar katalogu .git nie spadła:

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;) 

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD 
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66) 
rm 'test_data/images/001.jpg' 
[...snip...] 
rm 'test_data/images/281.jpg' 
Ref 'refs/heads/master' was rewritten 

$ git log -p # looks nice 

$ rm -rf .git/refs/original/ 
$ git reflog expire --all 
$ git gc --aggressive --prune 
Counting objects: 625, done. 
Delta compression using up to 2 threads. 
Compressing objects: 100% (598/598), done. 
Writing objects: 100% (625/625), done. 
Total 625 (delta 351), reused 0 (delta 0) 

$ du -hs .git 
174M .git 
$ # still 175 MB :-(
+9

tylko przypomnienie dla moderatorów, to pytanie 100% należy na SO, nie superużytkownikiem. – VonC

+0

Zobacz także http://stackoverflow.com/questions/2116778/reduce-git-repository-size/2116892#2116892 i http://stackoverflow.com/questions/685319/git-pull-error-unable-to-create -temporary-sha1-filename/685422 # 685422 – VonC

+0

Jak wspomniano tutaj (http://stackoverflow.com/questions/685319/git-pull-error-unable-to-create-temporary-sha1-filename/685422#685422), czy próbowałeś przepakować po swoim gc? 'git-repack -a' na przykład z" git-prune-packed ". Zobacz http://blog.felipebalbi.com/2007/12/19/housekeeping-your-git-repository/ – VonC

Odpowiedz

9

Ten poradnik removing sensitive data mogą ubiegać się, stosując tę ​​samą metodę. Będziesz przepisywać historię, aby usunąć ten plik z każdej wersji, w której był obecny. To jest destrukcyjne i spowoduje konflikty repo z innymi kasami, więc najpierw ostrzeż współpracowników.

Jeśli chcesz zachować plik binarny dostępny w repozytorium dla innych osób, to nie ma prawdziwego sposobu robienia tego, co chcesz. To prawie wszystko albo nic.

22

Twoja git reflog expire --all jest nieprawidłowa. Usuwa wpisy do rejestru, które są starsze niż czas wygaśnięcia, który domyślnie wynosi 90 dni. Użyj git reflog expire --all --expire=now.

My answer na podobne pytanie dotyczy problemu z szorowaniem nieużywanych obiektów z repozytorium.

5

Hy!

Git odbiera tylko obiekty to rzeczywiście potrzebne podczas klonowania repozytorium (jeśli rozumiem go poprawnie)

Więc można zmienić ostatni popełnić usuwając plik dodany przez pomyłkę, a następnie wciśnij zmian do zdalnego repozytorium (z - f opcja zastąpienia starego zatwierdzenia również na serwerze)

Następnie, gdy zrobisz nowy klon tego repo, jego katalog .git powinien być tak mały jak przed wielkim plikiem (-ami) zatwierdzonym.

Ewentualnie, jeśli chcesz, aby usunąć niepotrzebne pliki z serwera też można usunąć z repozytorium na serwerze i push nowo sklonowanych kopii (który ma pełną historię)

3
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all 

Pamiętaj, aby zmienić Filename dla tego, którego chcesz usunąć z repozytorium.

93

Odpowiedziałem na to gdzie indziej, a skopiuję tutaj, ponieważ jestem z tego dumny!

... i bez zbędnych ceregieli, mogę przedstawić Państwu ten przydatny skrypt, git-gc-wszystko, na pewno usunąć wszystkie swoje śmieci git dopóki nie może pochodzić z dodatkowych zmiennych konfiguracyjnych:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \ 
    -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \ 
    -c gc.pruneExpire=now gc "[email protected]" 

Opcja -aggressive może być pomocna.

UWAGA: spowoduje to usunięcie WSZYSTKICH bezrefleksyjnych przedmiotów, więc nie przychodź do mnie z płaczem, jeśli później zdecydujesz, że chcesz zatrzymać niektóre z nich!

Być może będziesz musiał również uruchomić coś takiego, o, kochanie, git jest skomplikowany !!

git remote rm origin 
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/ 
git for-each-ref --format="%(refname)" refs/original/ | 
    xargs -n1 --no-run-if-empty git update-ref -d 

umieścić to wszystko w skrypcie, tutaj:

http://sam.nipl.net/b/git-gc-all-ferocious

+0

Podobnie jak w http : //stackoverflow.com/questions/1904860/how-to-remove-unreferenced-blobs-from-my-git-popo/14728706#comment20614863_14728706, +1 do Ciebie ponownie. – VonC

+10

doskonałe: D mój zły plan, aby uzyskać więcej punktów poprzez klonowanie odpowiedzi zadziałało !! 1;) –

+0

Tak! To działało, ale musiałem uruchomić pełny skrypt. Uruchomienie tylko polecenia gc (z opcjami konfiguracji) nie było wystarczające. – Daniel

11

1) Usuń plik z repo git (& nie systemu plików):

  • git rm --cached path/to/file

2) termokurczliwa repo z:

  • git gc,

  • lub git gc --aggressive

  • lub git prune

lub kombinację powyższych, jak zaproponowano w tej kwestii: Reduce git repository size

+0

'git gc' pracował dla mnie! –

6

Klucz dla mnie wyrzucony, aby uruchomić git repack -A -d -f, a następnie git gc, aby zmniejszyć rozmiar pojedynczego pakietu git, jaki miałem.