Jak promazat git repositář a uvolnit tak místo na disku

Krátký návod, jak uvolnit místo na disku promazáním git repositáře. Nebudu raději ani popisovat, jak se stalo, že jsem do repositáře potvrdil (a ještě to poslal do nadřízeného repositáře) 30GB složku, ani co obsahovala. Poučením pro příště je, že git add -A je příliš mocná zbraň a to zejména v případě nenastaveného .gitignore. V mém případě jsem tedy potřeboval z repositáře vymazat velká data s cílem uvolnit místo na disku; tento návod ale platí i pro jakoukoliv situaci, kdy z repositáře budete potřebovat trvale smazat jakákoliv citlivá data, jako jsou hesla, soukromé klíče apod.

Tento návod je v podstatě volným překladem návodu na githubu.

Pracujeme na serverovém repositáři. V hierarchii gitu je to matoucí pojem, je samozřejmně možné pracovat na jakémkoliv repositáři, jen je třeba pamatovat, že na konci procesu si všichni zúčastnění budou muset naklonovat své repositáře znovu právě z tohoto opraveného.

Před samotnou prací je vhodné si udělat zálohu původního repositáře, u mě zafungovalo obyčejné git clone --bare Puvodni.git Opraveny.git. Díky tomu, že git clone na stejném systému souborů data nekopíruje, ale dělá jen hardlinky, je tato operace velmi rychlá.

Pěkná ukázka dobrého návrhu datových struktur a jednoduché implementace copy on write na obecném systému souborů. Jednou zapsaný soubor (platí pro datové soubory objektů, pack apod. nikoliv pro všechny soubory v repositáři) se nikdy nemění (jen třeba smaže po git gc), takže je možné snadno vytvářet clony repositářů ve stovkách kusů pomocí hardlinků a šetřit tak zabrané místo na disku.

Klonování nenahrazuje řádnou zálohu, pokud tedy tento postup chcete aplikovat na svůj vlastní soukromý repositář bez dalších jeho klonů umístěných na jiných počítačích, je vhodné jej před touto operací zazálohovat.

Samotné promazání, cílem je smazat složku JMENO_SLOZKY, jejíž jméno bylo v mém případě naštěstí unikátní.

git filter-branch --index-filter \ 
    'git rm -rf --cached --ignore-unmatch JMENO_SLOZKY' \
    --prune-empty --tag-name-filter cat -- --all

Při této operaci se přepisují revize, kde je daný soubor (složka) smazána a také všechny následující.

Samotné uvolnění místa na disku:

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --aggressive --prune=now

Poslední příkaz trval v mém případě 72GB repositáře několik hodin. Po jeho dokončení se repositář smrsknul na 22GB, což dobře odpovídá uloženým datům i objemu smazané a 2x změněné 30GB složky.

Po tomto kroku už následuje klasické git clone u všech klientů repositáře a také kontrola, zda v něm zůstala všechna potřebná data.

 

Příspěvek byl publikován v rubrice GIT. Můžete si uložit jeho odkaz mezi své oblíbené záložky.

4 komentáře: Jak promazat git repositář a uvolnit tak místo na disku

  1. Heron napsal:

    Jenom vysvětlující poznámku, protože se tomu stejně nejspíše nevyhnu :-D. Git používám pro svou běžnou práci a své pracovní dokumenty apod. Je to dobrý prostředek, jak si udržet pořádek a hlavně mít svá data na více počítačích synchronizovaná. Před čtyřmi lety jsem používal subversion http://www.heronovo.cz/poradek/, git je jen evoluce. Takže proto 22GB živých dat. Těch 30GB navíc byl samozřejmně omyl, proto jsem to chtěl smazat, jednalo se o disk virtuálního počítače).

  2. lzap napsal:

    Jak často děláš repack? Protože ten může docela trvat, s tak monstrózním repozitářem. Standardně to git dělá až po nějakém nastaveném prahu (počet souborů nebo dat – nevím přesně).

    • Heron napsal:

      Dělám občas (většinou po záloze na externí disk) git gc. Nepamatuji si, ze by někdy klient čekal na vyřízení git repack (nebo gc) na nadřízeném repositáři.

      $ time git gc
      Counting objects: 155772, done.
      Delta compression using up to 4 threads.
      Compressing objects: 100% (148940/148940), done.
      Writing objects: 100% (155772/155772), done.
      Total 155772 (delta 5882), reused 155772 (delta 5882)
      Checking connectivity: 155772, done.

      real 9m33.879s
      user 2m12.836s
      sys 0m41.455s

  3. Pingback: BTRFS v praxi po 5 letech | Heronovo

Komentáře nejsou povoleny.