Seite wählen

git filter-branch: Wie entfernt man Dateien aus der git Historie?

von | Feb 11, 2014 | DevOps, Development

By Jason Long (http://git-scm.com/downloads/logos) [CC-BY-3.0 (http://creativecommons.org/licenses/by/3.0)], via Wikimedia CommonsEs kommt immer wieder mal vor, dass unachtsame Kollegen die Videos von der letzten Netways Feier in das git-Repository der Puppet Konfiguration pushen. Wie man sofort merkt, funktioniert der git-hook zur Erkennung und Verhinderung von push Befehlen unter Restalkohol noch nicht so ganz…
Spaß bei Seite… wie kann man ungewollte (große) Dateien wieder aus git entfernen, welche das Repository nur aufblähen aber eigentlich nicht benötigt werden? Ein einfaches git revert entfernt zwar die Datei wieder aus der aktuellen Revision, aber in der History findet man ja Gott sei Dank trotzdem noch immer alles. Auch die Größe des Repositories bleibt gleich und mit jedem neuem Klon werden die unnützen Daten auch kopiert.
Um Dateien wirklich komplett aus dem git-Repository zu entfernen wird git filter-branch benötigt. Hiermit kann man die Historie neu schreiben, aber Achtung, dies bedeutet auch, dass bereits geklonte Repositories nicht mehr fast-forward fähig sind.
filter-branch läuft über jede Revision des aktuellen Branch und kann Kommandos auf die einzelnen Revisionen ausführen, z.B. ein git rm um Dateien zu löschen. Man kann die verschiedenen Elemente der Historie einzeln bearbeiten, in unserem Fall wollen wir den Index bearbeiten. Mit anderen Optionen könnte man z.B. die Commit-Message bearbeiten.
Mit folgendem Befehl wird das Video TWUndDieWeihnachtsmaenner.mpg aus allen Zweigen des Repository entfernt:
git filter-branch --prune-empty --index-filter "git rm --cached -f \
--ignore-unmatch TWUndDieWeihnachtsmaenner.mpg" -- --all

Was machen die Optionen im einzelnen?

  • –index-filter <command>: Mit diesem Filter schreibt man den Index neu.
  • –prune-empty: Durch das Filtern kann es passieren, dass leere Commits entstehen. Dank diesem Parameter werden solche Commits entfernt.
  • –all: Es werden alle Zweige es Repositories bearbeitet.
  • <command>: Im unserem Fall ist das <command> ein git rm.
    • –ignore-unmatch sorgt einfach nur dafür, dass 0 zurück gegeben wird, auch wenn es keine Datei zum löschen gibt.
    • –cache sorgt dafür, dass der aktuelle Working Tree nicht angefasst wird.
    • -f steht natürlich für force.

Als Ergebnis bekommt man ein bereinigtes Repositorie mit einer neuen Historie. Von diesem kann jetzt wiederrum geklont werden.
Wie man sieht ist es relativ viel Arbeit ein git Repository zu bereinigen. Zudem muss man das ursprüngliche Repository ersetzen und die Kollegen müssen dieses auch neu klonen.

Achim Ledermüller
Achim Ledermüller
Senior Manager Cloud

Der Exil Regensburger kam 2012 zu NETWAYS, nachdem er dort sein Wirtschaftsinformatik Studium beendet hatte. In der Managed Services Abteilung ist er für den Betrieb und die Weiterentwicklung unserer Cloud-Plattform verantwortlich.

0 Kommentare

Einen Kommentar abschicken

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Mehr Beiträge zum Thema DevOps | Development

Mein PHP-Trainingsprojekt

PHP Schulung Vor kurzem haben wir begonnen, eine neue Programmiersprache zu lernen – PHP. In der ersten Woche haben wir mit den Grundlagen wie Variablen, Arrays, Schleifen begonnen und uns schrittweise zu komplizierterer Syntax wie Funktionen, Objekten und Klassen...

check_prometheus ist jetzt öffentlich verfügbar!

Monitoring ist komplex, das wissen wir hier bei NETWAYS leider zu gut. Deswegen laufen in der Infrastruktur auch mal gerne mehrere Tools für die Überwachung. Zwei gern gesehene Kandidaten sind dabei Icinga und Prometheus. Icinga und Prometheus erfüllen...