weidner/archives/2026/09/

Mit git subtree andere Bibliotheken einbinden

Wenn ich ein Stück nicht triviale Software entwickle, teile ich die Entwicklung meist in drei Teile auf, die ich unabhängig voneinander verfolge:

Ein sofort einleuchtender Vorteil dieser Methodik ist, dass es die Fehlersuche erleichtert, weil ich mit dem Kommandozeilenprogramm schnell entscheiden kann, ob ein Problem eher in der Logik der Bibliothek zu suchen ist, oder in der Benutzerschnittstelle des Frameworks.

So gehe ich auch vor, wenn ich Analyzer für Cortex schreibe, die Informationen aus unserer lokalen Umgebung sammeln und für TheHive aufbereiten. Es gibt etliche Analyzer für Cortex, die die unterschiedlichsten Informationen bereitstellen. Doch für unseren lokalen Kontext und unsere konkrete Umgebung nützen diese meist wenig.

Einen Analyzer zu schreiben ist kein Hexenwerk, das ist gut beschrieben und dafür steht eine Python-Bibliothek auf PyPI bereit. Es fehlt nur noch die Programmlogik für unseren Kontext. Und hier greift die eingangs erwähnte Methodik.

Als erstes erstelle ich ein Python-Modul, welches die benötigten Informationen beschafft. Teil dieses Python-Moduls ist das Kommandozeilenprogramm, welches das API der Bibliothek verwendet und mit dem ich das Modul interaktiv ausprobiere und teste, bis es meinen Erwartungen entspricht.

Ist das Python-Modul fertig, schreibe ich den Analyzer, binde das Modul ein und erzeuge daraus einen Container, den Cortex dann aufrufen kann.

Und genau hier habe ich ein kleines Problem, wenn das Python-Modul nicht auf PyPI veröffentlicht ist. Das Dockerfile und der Python-Code für den Analyzer sind in einem Repository, das Python-Modul in einem anderen. Damit der Bau des Containers automatisch durchlaufen kann, müsste ich eine Referenz auf das zweite Repository mit einbauen - egal ob mit git submodule oder über einen Befehl in einem Skript. Damit würde ich jedoch eine Abhängigkeit herstellen, denn im Analyzer interessiert mich nicht, wo das Python-Modul ist, sondern nur was es macht.

Hier hilft mir git subtree (Tutorial bei Atlassian) womit ich den Quelltext des Python-Moduls in den Analyzer kopieren kann. Damit kann ich den Analyzer überall bauen, auch wenn das Repository des Python-Moduls nicht erreichbar ist. Trotzdem kann ich mit wenigen git Befehlen das kopierte Modul aus dem originalen Repository aktualisieren und Änderungen, die ich im Analyzer am Python-Modul vornehme, wieder an das originale Repository zurückschicken.

Wie gehe ich nun konkret vor? Da gibt es zwei Möglichkeiten. Ich kann die URL des Repositories bei git subtree direkt angeben, oder ich erstelle zunächst einen Verweis mit git remote, den ich dann bei den git subtree Befehlen referenziere.

Der zweite Weg ist zwar ein Schritt mehr, ermöglicht mir aber, die Befehle zum Aktualisieren und Zurückgeben von Änderungen in Skripts auszulagern, die ich nicht ändern muss, wenn sich die URL des Repositorys für das Python-Modul ändert. Ich muss lediglich den remote Eintrag bei Git entsprechend anpassen.

Darum ist mein erster Schritt:

git remote add -f $r_name $r_url

Hierbei ist $r_name der Name für das Repository, den ich in Skripten verwende und $r_url die aktuelle URL des Repositorys.

Anschließend füge ich den Inhalt ein:

git subtree add --prefix $pre $r_name $r_branch --squash

Dabei ist $pre der Pfad zu der Stelle, an der ich das Modul im Repository des Analyzers einfüge. Ich verwende meist modules/$modulname. $r_name hatten wir schon, $r_branch ist der Branch aus dem Modul-Repository, den ich einfügen will (meist main). Die Option --squash verwende ich, da mich beim Analyzer die Historie des Python-Moduls nicht interessiert.

So ist das Python-Modul direkt Bestandteil des Analyzers und ich brauche mir keine Sorgen mehr machen, woher ich es bekomme, wenn es nicht über PyPI verfügbar ist.

Will ich eine neuere Version des Moduls mit dem Analyzer verwenden, dann aktualisiere ich diese mit den folgenden Befehlen:

git fetch $r_name
git subtree pull --prefix $pre $r_name $r_branch --squash

Habe ich bei der Arbeit am Analyzer Änderungen an der Kopie des Moduls im Analyzer-Repository vorgenommen, kann ich diese mit folgenden Befehlen ins Modul-Repository zurückgeben:

git subtree push --prefix $pre $r_name $r_branch

Natürlich funktioniert das nur, wenn ich die nötige Berechtigung am Repository des Moduls habe. Fehlt mir diese, kann ich einen Patch mit folgendem Befehl extrahieren:

git diff $commit $pre

Dabei ist $commit der Commit, mit dem ich das Modul-Repository das letzte Mal einkopiert hatte. Diesen finde ich mit git log

Posted 2026-09-22
Tags: