Zum Hauptinhalt springen

Repository-Pflege: unerreichbare Objekte entfernen

Löschst du in Git einen Branch, einen Tag oder einen Pull Request, werden seine Commits dadurch nicht gelöscht. Die Commits werden unerreichbar: Keine Ref zeigt mehr auf sie, aber die Objekte bleiben auf dem Server und können von allen, die ihren SHA kennen, weiterhin abgerufen oder angesehen werden, bis Gits eigene Garbage Collection sie irgendwann später entfernt.

Unerreichbare Objekte entfernen entfernt sie sofort. Nutze das, wenn ein Commit nie hätte gepusht werden dürfen, zum Beispiel weil er ein Secret, personenbezogene Daten eines Kunden oder eine Datei enthielt, die du nicht speichern darfst. Owner der Organisation führen es selbst in der Konsole aus, und jeder Lauf endet mit einer schriftlichen Bestätigung, die du aufbewahren kannst.

Bevor du anfängst: Rotiere das Secret

Enthielt der Commit ein Secret (ein Passwort, einen API-Schlüssel, ein Token oder einen privaten Schlüssel), rotiere oder widerrufe zuerst das Secret. Das Entfernen des Commits macht das Secret nicht ungültig. Wer das Repository geklont oder gefetcht hat, während der Commit dort lag, hat eine Kopie, ebenso Forks, Mirrors und CI-Logs (siehe Was nicht entfernt wird). Das Entfernen begrenzt, wer den Commit ab jetzt bekommen kann; bereits vorhandene Kopien holt es nicht zurück.

Der Push-Schutz blockiert die meisten Secrets schon, bevor sie überhaupt den Server erreichen.

Wer es ausführen kann

Owner der Organisation. Die Seite liegt in der Organisationsverwaltung unter:

frem.sh/<your-org>/_admin/repos-overview/<repo>/housekeeping

Du brauchst Owner-Zugriff auf die Organisationsverwaltung, über deine normale Anmeldung, die eine Multi-Faktor-Authentifizierung verlangt. Einen weiteren Bestätigungsschritt darüber hinaus gibt es nicht. Um einen Lauf zu starten, tippst du den Repository-Namen vollständig ein, damit ein Lauf nicht versehentlich im falschen Repository gestartet werden kann.

Schritt für Schritt

  1. Rotiere jedes geleakte Secret. Siehe oben.
  2. Lösche, was den Commit enthält. Lösche jeden Branch, Tag oder Pull Request, der den Commit noch enthält, oder schreibe die Branch-Historie so um, dass der Commit nicht mehr dazugehört, und pushe mit Force. Ein Commit, den noch irgendeine Ref erreicht, ist nicht unerreichbar und wird beim Entfernen nicht gelöscht.
  3. Vorschau. Öffne die Pflegeseite und starte die Vorschau. Du kannst die SHAs der Commits einfügen, die verschwinden sollen (bis zu 20), und die Vorschau sagt dir für jeden, ob er entfernt wird oder was ihn noch hält. Siehe Die Vorschau lesen.
  4. Ausführen. Wähle, ob verwaiste LFS-Objekte einbezogen werden sollen, tippe zur Bestätigung den Repository-Namen ein und starte den Lauf. Die Seite zeigt seinen Fortschritt.
  5. Lade die Bestätigung herunter. Ist der Lauf abgeschlossen, lade die schriftliche Bestätigung als PDF oder JSON herunter und bewahre sie bei deinen Unterlagen zum Vorfall auf. Siehe Die schriftliche Bestätigung.

Die Vorschau lesen

Die Vorschau ändert nichts. Sie listet:

  • Für jeden eingefügten SHA: ob er im Repository existiert und, falls ihn noch eine Ref hält, welche (ein Branch, Tag, Pull Request oder eine andere Ref). Lösche diese Ref und starte die Vorschau erneut. Ein SHA, den nur noch ein Reflog-Eintrag hält, wird vom Lauf entfernt.
  • Unerreichbare Commits, die entfernt werden, mit der Betreffzeile ihrer Commit-Nachricht.
  • Unerreichbare Commits in der Schonfrist: zu neu, um sie jetzt zu entfernen. Siehe Die Schonfrist von 30 Minuten.
  • Forks des Repositorys, mit Namen. Ein Fork ist eine eigenständige Kopie und wird nicht verändert. Siehe Forks.
  • Weitere Elemente, die der Lauf entfernt: die Zahl der zwischengespeicherten Archiv-Downloads, der Einträge zur Branch-Wiederherstellung und, wenn du sie einbeziehst, der verwaisten LFS-Objekte.
  • Warum der Lauf nicht starten kann, falls er es nicht kann. Zum Beispiel: Für das Repository läuft bereits ein Lauf, oder das Repository liegt über der Größengrenze für Selbstbedienung.

Die Schonfrist von 30 Minuten

Objekte, die in den letzten 30 Minuten angelegt oder aufgefrischt wurden, bleiben immer erhalten. Das schützt Pushes, die gerade laufen, während der Lauf stattfindet: Ein Push schreibt seine Objekte, bevor er den Branch aktualisiert, und für diesen kurzen Moment sehen die neuen Objekte unerreichbar aus. Die Schonfrist ist fest und kann nicht verkürzt werden.

Steht ein Commit, den du entfernen willst, als in der Schonfrist in der Liste, warte, bis 30 Minuten vergangen sind, seit du gelöscht hast, was ihn hielt, starte die Vorschau erneut und dann den Lauf.

Was entfernt wird

  • Unerreichbare Git-Objekte: die Commits und die Trees und Dateiinhalte, die nur diese Commits verwenden, zusammen mit den Reflog-Einträgen, die sie noch hielten.
  • Der Commit aus dem Commit-Graph, sodass der Commit nicht mehr in Historienansichten, in der Suche oder über seinen SHA erscheint.
  • Zwischengespeicherte Archiv-Downloads (zip und tar) dieser Commits.
  • Zwischengespeicherte Kopien von Fetch-Packs für das Repository, die der Server vorhält, um wiederholte Clones und Fetches schneller zu beantworten.
  • Einträge zur Branch-Wiederherstellung für gelöschte Branches, die auf diese Commits zeigten, sodass der Branch nicht mehr aus der Liste der gelöschten Branches des Repositorys wiederhergestellt werden kann.
  • Optional verwaiste LFS-Objekte: LFS-Dateien, auf die kein Commit im Repository mehr verweist und die vor mehr als 24 Stunden hochgeladen wurden. Das wählst du beim Start des Laufs.

Ist der Lauf abgeschlossen, liefert eine URL, die den Commit zeigte, not found, und ein git fetch des SHA schlägt fehl.

Was nicht entfernt wird

Der Lauf entfernt Objekte aus diesem Repository auf den Servern von fremforge. Kopien, die anderswo liegen, erreicht er nicht, und Datensätze, die den Commit erwähnen, bearbeitet er nicht:

  • Forks. Jeder Fork ist eine eigenständige Kopie. Siehe Forks.
  • Bestehende Clones und Exporte. Jeder Clone, Fetch und Datenexport, der entstand, während der Commit da war, enthält ihn weiterhin. Bitte die Betroffenen, ihre Kopie zu löschen oder neu zu klonen.
  • Mirrors. Ein Mirror dieses Repositorys, auf fremforge oder anderswo, behält seine eigene Kopie.
  • Das Wiki des Repositorys. Das Wiki ist ein eigenes Git-Repository und wird nicht bereinigt.
  • Actions-Logs und -Artefakte. Ein Workflow, der auf dem Commit lief, kann dessen Inhalt ausgegeben oder gespeichert haben. Entferne diese gesondert.
  • Nutzdaten von Webhook-Zustellungen, die Commit-SHAs, Nachrichten und Angaben zum Autor enthalten.
  • Der Aktivitäts-Feed, Commit-Status und Kommentare in der Pull-Request-Timeline, die den Commit erwähnen.

Enthält eines davon etwas, das entfernt werden muss, und kannst du es nicht selbst entfernen, wende dich an support@frem.sh.

Forks

Ein Fork ist eine vollständige, eigenständige Kopie des Repositorys, und der Owner des Forks kontrolliert sie. Die Vorschau listet die Forks mit Namen, damit du weißt, wo der Commit sonst noch liegen kann. Um den Commit aus einem Fork zu entfernen, löscht der Owner des Forks dort den Branch, Tag oder Pull Request, der ihn hält, und führt das Entfernen im Fork aus, oder er löscht den Fork.

Backups

Das Entfernen löscht die Objekte aus dem laufenden Repository. Backups bearbeitet es nicht: Die Backups von fremforge werden nicht geändert, um die Daten eines einzelnen Kunden zu entfernen, und sie dienen nur der Wiederherstellung der Plattform, nie dazu, die Daten jemandem bereitzustellen. Ein entferntes Objekt bleibt daher in den verschlüsselten Backups, bis diese im Rahmen ihrer normalen Aufbewahrung ablaufen:

  • Repository-Inhalte (die Git-Objekte): bis zu 30 Tage.
  • Kopien im Objektspeicher (zwischengespeicherte Archiv-Downloads und LFS-Objekte): bis zu 13 Monate, im Speicher für die Notfallwiederherstellung.

Datenbankeinträge, etwa Einträge zur Branch-Wiederherstellung, folgen den Datenbank-Backups. Der Auftragsverarbeitungsvertrag, §9 und Anhang A.9, ist die verbindliche Aussage zu jeder Backup-Stufe und ihrer Aufbewahrungsdauer; wo diese Seite und der geltende AVV voneinander abweichen, gilt der AVV.

Die schriftliche Bestätigung

Jeder abgeschlossene Lauf erzeugt eine Bestätigung, die du als PDF oder JSON herunterladen kannst. Sie hält fest: das Repository, wer den Lauf wann ausgeführt hat, die Zahl der Objekte vor und nach dem Lauf, die Zahl der entfernten Archiv-Downloads, Einträge zur Branch-Wiederherstellung und LFS-Objekte sowie für jeden eingefügten SHA, ob er jetzt im Repository fehlt oder was ihn noch hält.

Bewahre sie bei deinen Unterlagen zum Vorfall auf. Sie ist dein Nachweis, wann die Daten aus dem laufenden Dienst entfernt wurden; der Abschnitt Backups oben nennt, wie lange danach noch Kopien bestehen.

Grenzen

  • Ein Lauf pro Repository und Stunde und 10 Läufe pro Organisation und Tag. Eine abgewiesene Anfrage zählt nicht.
  • Größengrenze für Selbstbedienung: 5 GiB. Für ein größeres Repository wende dich an support@frem.sh.
  • Bis zu 20 SHAs lassen sich in eine Vorschau einfügen.

API

Die Vorschau und die Ergebnisse eines Laufs lassen sich über die API lesen:

GET /_app/api/v1/orgs/{slug}/repos/{repo}/housekeeping/prune/preview?sha=<sha>[,<sha>...]

Der Status eines Laufs und seine schriftliche Bestätigung haben eigene GET-Endpunkte, die in der OpenAPI-Spezifikation aufgeführt sind.

Einen Lauf starten kannst du nur in der Konsole. Über die API lässt er sich nicht starten.