devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
0 4 minut

Odzyskiwanie wydajności Git w dużym repozytorium: sparse checkout


17.01.2013

 

Git jest the best – to wie chyba każdy kto czyta tego bloga. Może niekoniecznie się z tym zgadza, ale przynajmniej wie:). Wydaje mi się, że to jedyny kawałek softu, na który nigdy nie narzekałem…

Aż do niedawna. Przyszło mi pracować przy wieloletnim projekcie, którego repozytorium liczone było w gigabajtach. Za pomocą Git-TFS ściągnąłem sobie historię, a tam, jak się można domyślić, cały TfuFSowy syf. Czyli na przykład wszystkie branche będące kopiami, kropka w kropkę, plików pomiędzy jedną gałęzią a drugą (co za geniusz to w ogóle wymyślił?). Do tego masa dokumentów i starego kodu, z którym nie mam nic do czynienia. Okazało się, że Git niestety dostał zadyszki. Mimo 16GB RAMu, mimo SSD… (ciekawostka: niedawno Facebook też w tą pułapkę wpadł, tyle że oni pewnie z innych powodów). Rekomendowanym sposobem radzenia sobie z tym problemem jest odpowiednia organizacja kodu – dzielenie go na osobne repozytoria linkowane między sobą jako git submodules.

Z tym że jest jedno wielkie ALE – jeśli cały kod siedzi w TfuFS a ja sobie lokalnie używam Git to nic z tym nie zrobię. No ale jak to „nic z tym nie zrobię” skoro „git status” czy „git commit” trwają po kilkanaście sekund? Nie wspominając nawet o wielokrotnym rebase koniecznym przy komendzie rcheckin? I tak wolę takiego Gita niż TfuFSa, ale…

Na szczęście rozwiązanie się znalazło, i to prostsze niż można by się spodziewać. Taka a nie inna wydajność Gita spowodowana jest tym, że przy każdej operacji musi on przemielić te moje wszystkie gigabajty. Nic dziwnego, że się dusi (chociaż byłoby miło, gdyby tak nie było). Wystarczy jednak mieć w „working copy” tylko to co mi jest potrzebne, wszystkie pozostałe śmieci zostawiając w katalogu .git, i znowu jest cudownie! Mechanizm taki znany był już w SVN pod hasłem „partial checkout”. W Gicie nazywa się to „sparse checkout” i oto jak z jego dobrodziejstw można skorzystać:

Najpierw włączamy taki tryb pracy w konfiguracji repozytorium:

 git config core.sparsecheckout true 

Następnie tworzymy plik .git/info/sparse-checkout i wrzucamy do niego katalogi, które chcemy mieć w working copy. Wstawiamy jeden wpis per linia, np:

 Dev/Main
Config/Scripts

Możemy tutaj stosować patterns na nazwach plików i katalogów, jak w każdym innym miejscu Gita. Możemy też stosować negacje – wystarczy wykrzyknik z przodu linii.

Na koniec robimy użytek z powyższych czynności wywołując komendę:

 git read-tree -m -u HEAD 

I już. Cieszymy się ponownie niepokonaną szybkością działania.

Jeśli chcemy zmienić konfigurację sparse checkout to po prostu modyfikujemy plik ze ścieżkami i wykonujemy ponownie read-tree.

I tyle. Git znowu nie ma wad.

P.S. Gutek bardzo się ucieszył jak mu o tym powiedziałem, ale z innych powodów. Chciał zrobić checkout ZMIENIAJĄC strukturę katalogów – czyli na przykład żeby źródła trzymane w /root/dev/main/proj/src mieć bezpośrednio w /root/src. Takiego czegoś niestety nie ma.

UPDATE

Wygląda na to że to nie jest takie cudowne rozwiązanie – git tfs rcheckin wydaje się zdezorientowane zamieszaniem. checkintool nadal działa, ale moja ulubiona komenda z git-tfs nie chce. Zrobię kolejny update jeśli znajdę rozwiązanie, póki co założyłem issue na githubie.

UPDATE 2

Microsoftowy projekt Git-TF potrafi obsłużyć sparse checkouts, więc na razie przesiadam się na niego.

Nie przegap kolejnych postów!

Dołącz do ponad 9000 programistów w devstyle newsletter!

Tym samym wyrażasz zgodę na otrzymanie informacji marketingowych z devstyle.pl (doh...). Powered by ConvertKit
Powiadom o
trackback

Odzyskiwanie wydajności Git w dużym repozytorium: sparse checkout | Maciej Aniserowicz o programowaniu…

Dziękujemy za dodanie artykułu – Trackback z dotnetomaniak.pl…

pandominox
pandominox

Witam,

Można jeszcze spróbować polecenia git gc, albo najlepiej git gc –agressive. To także usuwa niepotrzebne śmieci i optymalizuje lokalne repo. Warto od czasu do czasu trochę „odświeżyć” w ten sposób repo.
Więcej info pod: http://www.kernel.org/pub/software/scm/git/docs/git-gc.html

Pozdrawiam, pandominox.

MWW
MWW

Na początku – dzięki – przekonałeś mnie jakiś czas temu do GIT-a i jestem równie entuzjastyczny :)

A teraz pytanie dotyczące posta:

Czy dobrze rozumiem że dzięki temu poleceniu można mieć w jednym repo np. 3 projekty (powiązane) i pracować tylko na jednym projekcie ?

Czyli:
Repo:
Projekt/główny program
Projekt/biblioteka API
Projekt/Biblioteka wewnętrna

I mogę ściągnąć tylko jeden katalog ? (np: projekt/główny program ?)

Pozdrawiam i dziękuję za bloga,
MWW

Michał Zalewski

Maciek, a nie probówałeś mapować tylko branch, na którym pracujesz bez innych branchy? Przykładowo tylko Projekt\main, a nie cały Projekt. Widzę, że istnieją foldery w głównym katalogu projektu (np. Config/Scripts), ale to też nie widzę problemu, żeby mapować je ręcznie.

zabanet
zabanet

Wygląda na to że już nie będziesz musiał narzekać na TfuFSa ;)
Sorki, że wrzucam to jako comment po niezbyt świeży post, ale jak się na to natknąłem, to od razu pomyślałem o Tobie: http://channel9.msdn.com/posts/GitForVisualStudioTFS
Pozdrawiam

trackback

[…] natknąłem się na ograniczenie w Git-TFS (chodzi o obsługę opisywanego sparse checkout). Skłoniło mnie to do przetestowania Git-TF… a poniżej moje […]

Moja książka „Zawód: Programista”

Facebook

Zobacz również