Co oznacza „Automatyczne pakowanie repozytorium w celu uzyskania optymalnej wydajności”?

225

Mam problem z moim repozytorium git. Przez ostatnie kilka dni, kiedy robię push na serwer, pojawia się komunikat: „Automatyczne pakowanie repozytorium dla optymalnej wydajności”, i wydaje się, że nie odchodzi i nie zwraca powłoki.

Próbowałem także sprawdzić się w nowej gałęzi, a następnie zrobić zmianę bazy na mojej poprzedniej gałęzi, a następnie zrobiłem git gcusunięcie nieużywanych obiektów historii, a następnie wykonałem wypychanie, ale nadal pojawia się ten komunikat. Daj mi znać, co się dzieje z moim repozytorium.

Furqan Asghar
źródło

Odpowiedzi:

305

Krótka wersja: oznacza to, co mówi, a jeśli po prostu pozwolisz jej zakończyć, wszystko będzie dobrze.

Podczas większości operacji, które mogą potencjalnie zwiększyć liczbę luźnych (rozpakowanych) obiektów w repozytorium (w tym wypycha), Git wywołuje git gc --auto. Jeśli jest wystarczająco dużo luźnych obiektów (domyślnie co najmniej 6700), wywoła je, git repack -d -laby je spakować. Jeśli jest zbyt wiele oddzielnych paczek, przepakuje je również w jedno.

Pakiet to pojedynczy plik skompresowany w formacie delta, zawierający dużą liczbę obiektów. Bardziej wydajne jest przechowywanie obiektów w paczkach, ale pakowanie (kompresowanie) obiektów wymaga czasu, więc Git początkowo tworzy luźne obiekty, a następnie od czasu do czasu pakuje je partiami, automatycznie wywołując git gc --auto.

Jeśli pozwolisz Gitowi zakończyć pakowanie, to się nie powtórzy. Może to rzeczywiście zająć trochę czasu, zwłaszcza jeśli masz dużo dużych obiektów binarnych, ale jeśli się uruchomi, oznacza to, że prawdopodobnie drastycznie zmniejszy ilość miejsca na dysku zajętego przez repo. Jeśli naprawdę nie chcesz, aby tak się stało, możesz zmienić parametr config gc.auto. Jeśli zwiększysz go do czegoś znacznie większego niż 6700, zdarzy się to rzadziej, ale zajmie to więcej czasu. Jeśli go zmniejszysz, nadal będziesz musiał wykonać bieżące przepakowanie, ale później będzie to miało miejsce częściej i zakończy się szybciej. Ustawienie wartości 0 spowoduje wyłączenie automatycznego przepakowywania.

Aby uzyskać więcej informacji, zobacz man git-gc(pod --auto) i man git-config(pod gc.auto).

Cascabel
źródło
14
Rzeczywiście zajęło mi to około 5 minut, ale skończyło się. Świetna odpowiedź.
Joshua Pinter
6
Widzimy, jak to się dzieje z każdym naciśnięciem (kilka sekund, heh).
2
@dpk: To nie powinno się zdarzyć w normalnych okolicznościach - liczba obiektów w jednym wypychaniu nie powinna być wystarczająco duża, aby ją wyzwolić (chyba że twoje repozytorium jest ogromne i / lub przepychasz mnóstwo zatwierdzeń), więc po pomyślnym zakończeniu kończy się (pozwalasz jej ukończyć, prawda?) nie powinno się to powtórzyć, dopóki się do tego nie zbudujesz. Jeśli nie możesz tego rozgryźć, zadaj osobne pytanie.
Cascabel
6
„Jeśli pozwolisz Gitowi skończyć” i możefatal: Out of memory, malloc failed (tried to allocate 79610689 bytes) error: failed to run repack- to właśnie dostaję za umieszczenie całej naszej bazy kodu w jednym repozytorium git. Zgaduję, że mam zamiar zabijać aplikacje i wymuszać przepakowanie „ręcznie”
ruffin
11
Dostaję to za każdym razem, gdy robię git. Zrobiłem ręczny git gc, ale wciąż się to zdarza za każdym razem, gdy ciągnę. Dziwne.
Barry Kelly,
51

Podczas gdy Jefroni ma rację, że czasami automatyczne pakowanie potrzebuje tylko czasu, aby zakończyć, jeśli komunikat automatycznego pakowania będzie się utrzymywał przez wiele dni, jak opisuje OP, istnieje duża szansa, że ​​podczas czyszczenia gita brakuje wiszących obiektów, jak opisano w tym pytaniu .

Aby sprawdzić, czy wiszące obiekty wyzwalają bieżące komunikaty o automatycznym pakowaniu, spróbuj uruchomić git fsck. Jeśli otrzymasz długą listę zwisających zatwierdzeń, możesz je wyczyścić

git gc --prune=now

Zwykle muszę uruchamiać to na moim repozytorium co 2-3 miesiące, gdy komunikat automatycznego pakowania nie zniknie po jednym pociągnięciu.

wbharding
źródło
5
Chociaż nie była to zaakceptowana odpowiedź, tego właśnie potrzebowałem. Dostawałem wiadomość za każdym razem, gdy robiłem to git pullprzez kilka dni, i fsckrzeczywiście pokazywałem mnóstwo zwisających zobowiązań.
Jörn Zaefferer
36

Aby wyłączyć dla jednego projektu:

cd your_project_dir
git config gc.auto 0

Aby wyłączyć globalnie:

git config --global gc.auto 0
Anders Lindén
źródło
2
Myślę, że dowiedziałem się, jak: przejść do folderu .git, otworzyć plik konfiguracyjny, usunąć tekst „auto = 0” i zapisać. To wydaje się ponownie włączać automatyczne pakowanie.
Adrian Keister
18
git config --unset gc.auto
jtatum
10

Git uruchamia git-repack, który pakuje wiele obiektów (= pliki, zatwierdzenia i drzewa) w jeden plik pakietu. Git robi to czasami, gdy heurysta mówi, że można zaoszczędzić miejsce (plik paczki zawiera skompresowane delty obiektów, a każdy plik w katalogu objects / zawiera skompresowaną pełną zawartość pliku)

Rudi
źródło
2

Mamy nadzieję, że ten git gc --autokrok jest teraz (git 2.0.1, 25 czerwca 2014 r.) Bardziej wydajny.
Zobacz commit 62aad18 autor: Nguyễn Thái Ngọc Duy ( pclouds)

gc --auto: nie blokuj odnośników w tle

9f673f9 ( gc: opcja konfiguracji do uruchamiania --auto w tle - 08.02.2014, Git 2.0.0) umieszcza „ gc --auto” w tle, aby skrócić czas oczekiwania użytkownika.
Częścią wyrzucania elementów bezużytecznych są pakiety referencji i dzienniki czyszczenia. Wymagają one zablokowania niektórych referencji i mogą przerwać inne procesy próbujące zablokować tę samą referencję.

Jeśli gc --autozostanie wystrzelony w środku skryptu, blokada przytrzymywania gc w tle może zawieść skrypt, co nigdy nie mogłoby się zdarzyć przed 9f673f9 .

Biegnij dalej pack-refs i „ reflog --prune” na pierwszym planie, aby zatrzymać równoległe aktualizacje referencyjne. Pozostałe operacje w tle (przepakowywanie, przycinanie i ponowne pobieranie) nie powinny wpływać na uruchomione procesy git.

A Git 2.22 (drugi kwartał 2019 r.) Dodatkowo optymalizujegit gc .

VonC
źródło