Note: yay cache .git root cause, find -prune/-delete gotcha, paccache timer
This commit is contained in:
@@ -22,11 +22,50 @@ Fehlermeldung (Beispiel `supersonic-desktop`, August 2026):
|
||||
## Ursache
|
||||
|
||||
Der lokale Klon des AUR-Repos in yays Cache (`~/.cache/yay/<paket>`) ist **korrupt**.
|
||||
Typisch: der `.git`-Ordner ist unvollständig (z. B. fehlen `HEAD` oder `config`),
|
||||
meist nach einem abgebrochenen Clone/Pull oder einer gestörten Synchronisation.
|
||||
Typisch: der `.git`-Ordner ist unvollständig (z. B. fehlen `HEAD` oder `config`).
|
||||
|
||||
Das AUR-Paket selbst ist in Ordnung – nur die lokale Kopie ist kaputt.
|
||||
|
||||
### Mögliche Auslöser
|
||||
|
||||
1. Abgebrochener Clone/Pull oder eine gestörte Synchronisation
|
||||
2. **Aggressive Cache-Bereinigung** (realer Fall, September 2026) – siehe unten
|
||||
|
||||
### Ursache 2: Cache-Cleanup hat die `.git`-Metadaten gelöscht
|
||||
|
||||
Der AUR-Cache unter `~/.cache/yay` ist selbst nur ein Build-Cache. Wird er per
|
||||
`find` mit Alterskriterium aufgeräumt, greift die Suche **auch in die `.git`-Ordner**
|
||||
hinein und löscht dort genau die Dateien, die Git zum Erkennen eines Repos braucht:
|
||||
|
||||
```bash
|
||||
# 2026-04-24 ausgeführt – hat 24 AUR-Klone gleichzeitig zerstört
|
||||
find ~/.cache -type f -atime +30 -delete
|
||||
```
|
||||
|
||||
Ergebnis pro betroffenem Paket:
|
||||
|
||||
| Datei | Status | Warum |
|
||||
|-------|--------|-------|
|
||||
| `.git/HEAD` | **gelöscht** | seit dem Clone (13.02.) nicht mehr geschrieben → >30 Tage alt |
|
||||
| `.git/config` | **gelöscht** | dito |
|
||||
| `.git/description` | **gelöscht** | dito |
|
||||
| `.git/hooks/*.sample` | gelöscht | dito |
|
||||
| `.git/info/exclude` | gelöscht | dito |
|
||||
| `.git/logs/**` (Reflog) | gelöscht | dito |
|
||||
| `.git/index` | überlebt | beim Build am 19.04. neu geschrieben → <30 Tage |
|
||||
| `.git/ORIG_HEAD` | überlebt | dito |
|
||||
| `.git/objects/**` | überlebt | nur gelesen, nicht geschrieben |
|
||||
| `.git/refs/**` | überlebt | dito |
|
||||
|
||||
**Warum genau `HEAD` und `config` fehlen:** Git erkennt ein Repository anhand von
|
||||
`HEAD` + `objects` + `refs`. Fehlt `HEAD`, gilt der Ordner nicht mehr als Repository –
|
||||
daher die Fehlermeldung, obwohl der Ordner und die Objekte noch da sind.
|
||||
|
||||
Der entscheidende Punkt: Auf einem **`noatime`-Mount** aktualisiert Lesen die Zugriffszeit
|
||||
nicht mehr. `-atime +30` bedeutet dort also *"seit 30 Tagen nicht mehr **geschrieben**"* –
|
||||
und nicht *"seit 30 Tagen nicht benutzt"*. Genau deshalb wurden auch Klone gelöscht,
|
||||
die täglich gelesen wurden. Details: [[IT-Know-How/Linux/BASH Basics/find]].
|
||||
|
||||
---
|
||||
|
||||
## Diagnose
|
||||
@@ -39,6 +78,47 @@ git -C ~/.cache/yay/<paket> status
|
||||
|
||||
Kommt dieselbe Meldung („Kein Git-Repository"), obwohl der Ordner existiert → Cache-Klon löschen.
|
||||
|
||||
Schnellcheck des `.git`-Inhalts:
|
||||
|
||||
```bash
|
||||
ls ~/.cache/yay/<paket>/.git
|
||||
# Erwartet: HEAD config objects refs index ...
|
||||
```
|
||||
|
||||
### Warum meldet `yay -Ss` keinen Fehler?
|
||||
|
||||
`yay -Ss` fragt die AUR-RPC-Schnittstelle per HTTP ab und braucht den lokalen Klon
|
||||
dafür nicht. Erst `yay -S`/`-Syu` führt ein `git pull` im Cache-Ordner aus – daher
|
||||
funktioniert die *Suche*, während das *Installieren/Updaten* fehlschlägt.
|
||||
|
||||
### Forensik: eigene Hausarbeit prüfen
|
||||
|
||||
Falls unklar ist, **wann** und **wodurch** die Klons zerstört wurden, hilft der
|
||||
Dateisystem-Zeitstempel. Alle betroffenen `.git`-Ordner tragen denselben mtime,
|
||||
weil ein einziger Prozess sie in einem Durchlauf angefasst hat:
|
||||
|
||||
```bash
|
||||
# Alle zerstörten Klons finden
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
! -exec test -f '{}/HEAD' \; -printf '%h\n'
|
||||
|
||||
# mtime vergleichen (hier: alle exakt 2026-04-24 12:29:16)
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
-printf '%T+ %h\n' | sort
|
||||
```
|
||||
|
||||
Der Zeitstempel lässt sich gegen die Shell-History abgleichen:
|
||||
|
||||
```bash
|
||||
# fish: Epoch-Sekunden der History-Einträge umrechnen
|
||||
grep -n 'atime' ~/.local/share/fish/fish_history
|
||||
date -d @1777026555 # → 2026-04-24 12:29:15 CEST
|
||||
```
|
||||
|
||||
Ein im Nanosekunden-Bereich aufeinanderfolgender Versatz zwischen den Verzeichnissen
|
||||
(`.4006957730`, `.4016957760`, …) bestätigt einen einzelnen `find`-Durchlauf statt
|
||||
manueller Eingriffe.
|
||||
|
||||
---
|
||||
|
||||
## Lösung
|
||||
@@ -54,6 +134,27 @@ yay klont das PKGBUILD-Repo beim nächsten Lauf frisch – danach funktioniert d
|
||||
|
||||
---
|
||||
|
||||
## Alle betroffenen Pakete auf einmal reparieren
|
||||
|
||||
Sind mehrere Klons betroffen (z. B. nach einem pauschalen Cleanup), alle auf einmal
|
||||
finden und entfernen. `-printf '%h'` liefert den übergeordneten Paketordner, `%h\0`
|
||||
plus `xargs -0` ist gegen Leerzeichen in Pfaden sicher:
|
||||
|
||||
```bash
|
||||
# 1. Erst ansehen – nur anzeigen, nicht löschen
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
! -exec test -f '{}/HEAD' \; -printf '%h\n'
|
||||
|
||||
# 2. Dann entfernen
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
! -exec test -f '{}/HEAD' \; -printf '%h\0' | xargs -0 rm -rf
|
||||
```
|
||||
|
||||
Betroffen sind nur unbrauchbare Klone. yay klont sie beim nächsten Build neu;
|
||||
installierte Pakete bleiben unberührt.
|
||||
|
||||
---
|
||||
|
||||
## Allgemein: yay-Cache aufräumen
|
||||
|
||||
| Vorgehen | Befehl | Folge |
|
||||
@@ -64,3 +165,68 @@ yay klont das PKGBUILD-Repo beim nächsten Lauf frisch – danach funktioniert d
|
||||
|
||||
**Faustregel:** Immer erst den einzelnen Paketordner löschen. Den kompletten Cache nur leeren,
|
||||
wenn mehrere Pakete betroffen sind – er enthält nichts Kritisches, kostet aber Rebuild-Zeit.
|
||||
|
||||
| Befehl | Wirkung |
|
||||
| --- | --- |
|
||||
| `yay -Sc` | Entfernt Build-Artefakte (untracked/gitignored) aus den Paketordnern, fragt zusätzlich nach dem Pacman-Cache |
|
||||
| `yay -Scc` | Wie `-Sc`, leert aber **alle** AUR-Build-Ordner vollständig (inkl. `.git`) |
|
||||
| `paccache -rk2` | Pacman-Cache aufräumen, 2 Versionen behalten – siehe [[IT-Know-How/Linux/Pacman Paketcache verwalten]] |
|
||||
|
||||
> **Vorsicht bei `yay -Scc`:** Nimmt auch die `.git`-Ordner mit, d. h. alles wird beim
|
||||
> nächsten `-Syu` neu geklont. Für einen Cache dieser Größe unkritisch, aber langsam bei
|
||||
> vielen AUR-Paketen mit langen Buildzeiten.
|
||||
|
||||
### Was der AUR-Cache tatsächlich belegt
|
||||
|
||||
Ein Build hinterlässt je Paket teure Dateien im Cache-Ordner: das heruntergeladene
|
||||
Quell-Archiv bzw. AppImage und das fertige `.pkg.tar.zst`. Im September 2026 belegten
|
||||
vier alte LM-Studio-Versionen allein 7,1 GB (4 × AppImage + 4 × fertiges Paket).
|
||||
|
||||
Diese Artefakte sind exakt das, was die `.gitignore` der AUR-Repos ausschließt
|
||||
(`*.AppImage`, `*.pkg.tar.zst`, `src/`, `pkg/`, `*.tar.gz`, …) – deshalb entfernt
|
||||
`yay -Sc` / `git clean -xdf` sie zuverlässig.
|
||||
|
||||
Gezielt aufräumen – Prüfen und Löschen getrennt, weil `-delete` und `-prune` nicht
|
||||
kombinierbar sind:
|
||||
|
||||
```bash
|
||||
# 1. Prüfen: Anzahl und Größe (darf -prune verwenden, da nur -print)
|
||||
find ~/.cache/yay -name .git -prune -o -type f \
|
||||
\( -name '*.pkg.tar.zst' -o -name '*.AppImage' -o -name '*.deb' \
|
||||
-o -name '*.tar.gz' -o -name '*.tar.xz' \) -printf '%s\n' \
|
||||
| awk '{s+=$1;n++} END {printf "%d Dateien, %.2f GB\n", n, s/1024/1024/1024}'
|
||||
|
||||
# 2. Löschen: OHNE -prune, stattdessen .git über -not -path ausnehmen
|
||||
find ~/.cache/yay -type f \
|
||||
\( -name '*.pkg.tar.zst' -o -name '*.AppImage' -o -name '*.deb' \
|
||||
-o -name '*.tar.gz' -o -name '*.tar.xz' \) \
|
||||
-not -path '*/.git/*' -delete
|
||||
```
|
||||
|
||||
> **Warum zwei Befehle?** `-delete` schaltet intern auf `-depth` um, und `-prune`
|
||||
> ist dann wirkungslos – der `.git`-Schutz fällt weg. Zum Zählen/Lösen ist `-prune`
|
||||
> mit `-print` ok, beim Löschen aber durch `-not -path '*/.git/*'` ersetzen. Details:
|
||||
> [[IT-Know-How/Linux/BASH Basics/find]].
|
||||
|
||||
---
|
||||
|
||||
## Prävention
|
||||
|
||||
Damit das nicht noch einmal passiert:
|
||||
|
||||
1. **Kein `-delete` über `~/.cache` ohne `.git`-Ausschluss.** Immer `-not -path '*/.git/*'`
|
||||
verwenden, niemals `-prune` (das ist unter `-delete` wirkungslos).
|
||||
2. **Besser gar nicht pauschal aufräumen.** `~/.cache/yay` ist ein reiner Build-Cache und
|
||||
enthält nichts Unwiederbringliches – `yay -Sc` ist der vorgesehene Weg.
|
||||
3. **Auf `noatime`-Mounts `-atime` nicht als „letzte Nutzung" lesen.** Vorher prüfen:
|
||||
`findmnt -T /home`
|
||||
4. **Regelmäßig `paccache -rk2`** – der Pacman-Cache wächst unbegrenzt und war mit
|
||||
66 GB der eigentliche Plattenfresser (siehe [[IT-Know-How/Linux/Pacman Paketcache verwalten]]).
|
||||
|
||||
---
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[IT-Know-How/Linux/BASH Basics/find]] - `-delete`/`-prune`-Konflikt und `noatime`
|
||||
- [[IT-Know-How/Linux/Pacman Paketcache verwalten]] - `paccache` und der Pacman-Cache
|
||||
- [[IT-Know-How/Linux/Paketinstallation in Linux-Distributionen]] - pacman/yay Grundbefehle
|
||||
|
||||
Reference in New Issue
Block a user