2013-04-17 10 views
9

więc pracuję z kilkoma przyjaciółmi i wszyscy jesteśmy nowi w git i jeden z nich popełnił dużą ilość zewnętrznych plików binarnych, które spowalnia repozytorium, i zajmuje duży dysk -przestrzeń.git wolne miejsce na dysku, usuwając historię repozytorium

Właśnie rozpoczęliśmy projekt, więc nie ma w nim nic ważnego oprócz pliku readme. Więc chcielibyśmy wyczyścić historię repozytorium do bieżącego stanu.

So basicly it looks this: 

Head -> A -> B -> C total disk size 45 MB, 1 file, 300 deleted files 

And we want this: 

Head -> A    total disk size 1 kB, 1 file, 0 deleted files 

Oczywistym rozwiązaniem byłoby utworzenie nowego repozytorium i skopiowanie pliku readme do nowego repozytorium. Chciałabym jednak nauczyć się czegoś dla celów edukacyjnych/ciekawości, jeśli istnieje polecenie GIT, które może to zrobić.

Eksperymentowałem z poleceniem Rebase, ale wygląda na to, że nadal zachowuje starą historię i swoje dane, co wprowadza mnie w błąd, ponieważ jeśli zmiana bazy danych nie spowoduje wyczyszczenia danych z repozytorium, możesz również nie używać go.

Przeszukałem kilka innych postów na ten temat i podejrzewam, że nie można tego zrobić z git. Chciałbym jednak to potwierdzić.

I tak to jest zdalny katalog na github

Dzięki za wszelką pomoc.

Więc dla mojego rozwiązania wybrałem zrobić:

rebase using tortoisegit 
squash all commits 
then using git bash: 
git reflog expire --all --expire-unreachable=now 
git gc --aggressive --prune=now 
git push origin master --force 

To nie wydaje się lokalną historią repozytorium chce się kurczyć w wielkości dysku. Jednak klonowanie repozytorium ponownie pokazuje pożądane wyniki i rozmiar dysku. A także log repozytorium.

Dzięki za pomocne odpowiedzi. Interesujący Rebase wydaje się bardzo silny.

+0

'git gc' daje mi taką samą redukcję rozmiaru jak klonowanie repozytorium na nowo, FWIW. – rogerdpack

Odpowiedz

6

Rebasing (git rebase -i --root, jeśli nie przywróciłeś złego zatwierdzenia, po prostu usuń jego linię, jeśli tak zrobiłeś, zmiażdż złym zatwierdzeniem z zatwierdzeniem rewersji) lub użycie gałęzi filtra wyczyści dane z twojego oddziału historię, ale nie sprawi, że zniknie całkowicie z repozytorium.

Dzieje się tak, ponieważ ze względów bezpieczeństwa i możliwości śledzenia, git przechowuje reflog (widoczny z git log -g), który śledzi każdy zatwierdzenie, które zrobiłeś, niezależnie od tego, czy nadal jest częścią wykresu przodków.

Klonowanie przefiltrowaną repo nie będzie klonować ukrytych danych, a także można go usunąć na miejscu z tych poleceń:

git reflog expire --all --expire-unreachable=now 
git gc --aggressive --prune=now 

polecenia te nie są normalnie zalecanymi i bez odnośników commity wygaśnie w 30 dni w każdym razie, ale ponieważ twoje repozytorium jest praktycznie nowe, nie ryzykujesz zbyt wiele.

4

Nie musisz całkowicie tracić historii. Możesz po prostu przepisać go, używając filter-branch. To dość destrukcyjne polecenie, więc najpierw wykonaj kopię. Ten przykład przejdzie przez historię usuwania wszystkich plików jar.

git filter-branch --tree-filter 'git rm **/*.jar' 

Dostosuj, aby dopasować to, co gigantyczne pliki zostały przypadkowo dodane. Zauważ, że modyfikowanie zatwierdzeń zmienia ich identyfikator, więc użytkownicy prawdopodobnie będą chcieli ponownie sklonować repozytorium po tym, aby uniknąć strasznych konfliktów. Będziesz także musiał --force odesłać do repozytorium, ponieważ git będzie narzekał (słusznie), że historia bardzo się zmieniła.

Lokalne transakcje repo może nie zmniejszyć się natychmiast, dopóki nie zdecyduje się na zbieranie śmieci.

+0

Pliki, które chcę usunąć, znajdowały się w folderze, który już nie istnieje. , więc ciągle pojawia się ten błąd "FolderName/*" nie pasuje do żadnych plików – ColacX

1

Może chcesz przejrzeć Squashing all Git commits into a single commit. To również odnosi się do pytania o przepełnienie stosu - które można nazwać duplikatem - tutaj: How to squash all git commits into one?

Rozwiązanie wspomniane przez Wincenta w pierwszym linku znajduje się w połowie strony. Szybki test na miejscu pokazuje, że działa tak, jak jest reklamowany. W celach informacyjnych, Wincent proponuje:

git update-ref -d refs/heads/master 
git commit -m "Initial import" 

FWIW, prawdopodobnie będziesz musiał uruchomić git gc --prune=now oczyścić żadnych przedmiotów bez odniesień. A kiedy wypchniesz nowego mistrza, musisz użyć --force. Powinieneś prawdopodobnie utworzyć kopię zapasową przed wypróbowaniem którejkolwiek z tych sytuacji.:-)

Powiązane problemy