Select Page

GIT – aus eins mach viele

by | Aug 15, 2013 | Development

Software Projekte starten meist mit einem SCM Repository. Nach einem gewissen historisch bedingten Wachstum hat man dann auf einmal eine Sammlung unabhängiger Komponenten. Diese gehören aber in eigene Repositories. Gerade wenn unterschiedliche Versionen in der Produktion zum Einsatz kommen sollte man tunlichst darauf achten. Sonst wird es schwer unabhängig voneinander zu entwickeln ohne Kompatibilität zu brechen.
Leider hat man es zu spät gemerkt. Was tun um die Historie nicht zu verlieren? In den dunklen Ecken von GIT findet sich git-filter-branch. Ein mächtiges Tool wenn es darum geht am kompletten Baum etwas zu verändern. Aber beginnen wir von vorne:
1. Repository auschecken:

$ git checkout git@git.foo.bar:repository.git && cd repository

2. Entfernen aller anderen Verzeichnisse bis auf das gewollte

$ git filter-branch --prune-empty --subdirectory-filter path/to/component -- --all

Mit dem obigen befehl wird alles entfernt was nicht im Verzeichnis ‘path/to/component’ vorkommt. Normalerweise werden hierbei leere commits erzeugt welche nichts mit dem Filter zu tun haben. Um dies zu vermeiden gibt es die Option ‘–prune-empty’.
3. Anlegen eines neuen Repositories und setzen eines neuen Ziels

$ git remote add target git@git.foo.bar:component.git

4. Explizites pushen des master branch in das neue Ziel

$ git push target master

Neues Repository wird mit der gefilterten Historie gefüllt. Allerdings ist der alte Code noch im ehemaligen Repository vorhanden
5. Neu auschecken und redundanten Code entfernen
Lokale Kopie von der Platte entfernen (Schritt 1) und mit folgendem GIT Befehl weiterarbeiten

$ git filter-branch --tree-filter ' rm -rf path/to/component' HEAD

6. Repository pushen und aufräumen
Wir haben die Timeline geändert und unsere Änderungen passen sich nicht mehr in die Historie ein:

$ git push -f

Mit der Option -f wird alles Remote überschrieben, egal ob es passt oder nicht. Man tun gut daran kurz inne zu halten und den Branch zu überprüfen.
Danach können wir die alten Reflogs löschen um Speicherplatz frei zu geben:

$ git reflog expire --expire=now --all && git gc --aggressive --prune=now

Pa-Tsching – fertig!
Natürlich ist das nicht die ganze Wahrheit und passt auf einfach Anwendungsfälle. Mit unterschiedlichen Release Tags und verzweigten Branches wird das extrahieren etwas aufwendiger. Allerdings ist dies dann keine Standardfall mehr und genau auf das Projekt zugeschnitten (Namensschemata usw.).
Detail Informationen finden sich auf der Manpage von GIT.

Marius Hein
Marius Hein
Head of IT Service Management

Marius Hein ist schon seit 2003 bei NETWAYS. Er hat hier seine Ausbildung zum Fachinformatiker absolviert und viele Jahre in der Softwareentwicklung gearbeitet. Mittlerweile ist er Herr über die interne IT und als Leiter von ITSM zuständig für die technische Schnittmenge der Abteilungen der NETWAYS Gruppe. Wenn er nicht gerade IPv6 IPSec Tunnel bohrt, sitzt er daheim am Schlagzeug und treibt seine Nachbarn in den Wahnsinn.

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

More posts on the topic 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...