Intelligente Lösungen
in neuer Dimension

Git-Verzeichnis komprimieren

Bei mir gibt es ein Git-Repo mit “schwankendem” Platzbedarf:

  • Früher war es mal sehr groß
  • Dann hat ein Kollege die Historie bereinigt/gekürzt
  • Jetzt verbraucht es diesen Plattenplatz:
    • Frischer git clone: 100M
    • Alter git clone: 440M
    • Repo auf GITEA: 730M

Ziel dieser Beschreibung ist die Komprimierung des alten Clones und des Repos auf GITEA.

Alten Clone komprimieren

Ausgangslage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ du -hs .
437M  .

$ du -hs .git
386M  .git

$ git count-objects -v
count: 0
size: 0
in-pack: 15740
packs: 1
size-pack: 394027
prune-packable: 0
garbage: 0
size-garbage: 0

prune und gc

Versuch der Bereinigung mit git prune und git gc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git prune --expire now
$ git gc

$ du -hs .
437M  .

$ git count-objects -v
count: 0
size: 0
in-pack: 15740
packs: 1
size-pack: 394027
prune-packable: 0
garbage: 0
size-garbage: 0

Bringt nix!

gc —aggressive

Noch ein Versuch mit git gc --aggressive:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ git gc --aggressive
  # Dauert eine ganze Weile
Objekte aufzählen: 15740, fertig.
Zähle Objekte: 100% (15740/15740), fertig.
Delta-Kompression verwendet bis zu 16 Threads.
Komprimiere Objekte: 100% (13146/13146), fertig.
Schreibe Objekte: 100% (15740/15740), fertig.
Gesamt 15740 (Delta 8445), Wiederverwendet 6936 (Delta 0), Pack wiederverwendet 0

$ du -hs .
434M  .
$ git count-objects -v
count: 0
size: 0
in-pack: 15740
packs: 1
size-pack: 390550
prune-packable: 0
garbage: 0
size-garbage: 0

Bringt nix!

expire

1
2
3
4
5
6
7
8
9
10
11
$ git reflog expire --expire-unreachable=now --all
$ git gc --prune=now
Objekte aufzählen: 854, fertig.
Zähle Objekte: 100% (854/854), fertig.
Delta-Kompression verwendet bis zu 16 Threads.
Komprimiere Objekte: 100% (456/456), fertig.
Schreibe Objekte: 100% (854/854), fertig.
Gesamt 854 (Delta 282), Wiederverwendet 796 (Delta 250), Pack wiederverwendet 0

$ du -hs .
96M   .

Super!

Gitea-Repo komprimieren

Garbage-Collection auf Repositories ausführen

Innerhalb von Gitea:

  • Benutzer/Uli oben rechts
  • Administration
  • Garbage-Collection auf Repositories ausführen – Ausführen!

Hilft ein wenig:

  • Davor: 730 MB
  • Danach: 385 MB

expire analog zum clone

1
2
3
4
5
6
7
8
9
10
11
$ git reflog expire --expire-unreachable=now --all
$ git gc --prune=now

$ du -hs .
386M  .

$ git gc --aggressive
  # Dauert eine ganze Weile

$ du -hs .
383M

Diverse weitere Experimente

Ich habe noch diese Dinge ausprobiert:

1
2
3
4
5
6
7
8
9
git reflog expire --expire-unreachable=now --all
git gc --prune=now
git gc --aggressive
git prune --expire now
git fsck --unreachable
git fsck --unreachable --dangling --full
git repack -a -d -f --depth=250 --window=250

git clone --bare riskradarkonzern.git r

Alle bringen nix!

Vergleich lokales Repo mit Gitea-Repo

  1. “Bare”-Variante vom lokalen Repo erzeugen: git clone --bare (meinrepo) (meinrepo).git2
  2. Sichten der Größe: du -hs (meinrepo); du -hs (meinrepo).git2
    • (meinrepo): 96M
    • (meinrepo).git2: 45M
  3. Vergleich

Es stellt sich heraus, dass im Gitea-Repo diese Dateien zusätzlich vorhanden sind:

  • ./FETCH_HEAD
  • ./info/refs
  • ./objects/info/commit-graph
  • ./logs/HEAD
  • ./logs/refs/heads/master

Sichten von “logs/refs/heads/master” gibt Hinweise auf PullRequests. Idee: Wir löschen alle PullRequests und schauen!

1
2
3
4
5
6
7
8
9
10
11
12
$ git reflog expire --expire-unreachable=now --all
$ git gc --prune=now
Enumerating objects: 854, done.
Counting objects: 100% (854/854), done.
Delta compression using up to 8 threads
Compressing objects: 100% (431/431), done.
Writing objects: 100% (854/854), done.
Building bitmaps: 100% (39/39), done.
Total 854 (delta 275), reused 854 (delta 275), pack-reused 0

$ du -hs .
45M   .

Zusammenfassung

Wenn die Historie eines sehr großen Repos überarbeitet und/oder gekürzt wird, so sind diese Schritte notwendig damit der Plattenplatz freigegeben wird:

  • Lokaler Clone
1
2
git reflog expire --expire-unreachable=now --all
  git gc --prune=now
  • Gitea-Repo

    • Alle alten Zweige (branches) löschen
    • Alle alten PullRequests löschen
    • Im Gitea-Container:
1
2
3
4
cd .../gitea-repositories
    cd (gruppe)/(repo).git
    git reflog expire --expire-unreachable=now --all
    git gc --prune=now

Das Endergebnis überzeugt:

Ort Alter Platzbedarf Neuer Platzbedarf
Lokaler Clone 440M 100M
Gitea-Repo 730M 50M

Links

Änderungen

  • 2023-08-11: Erste Version