Softwareprojekte, die SVN als Versionskontrollsystem nutzen und modular aufgebaut sind, profitieren davon, einzelnen Module unter einem Parent-Repository gemeinsam zu verwalten. In SVN ist es daher nicht unüblich, eine Projektstruktur zu verwenden, die eine klare Trennung der Module ermöglicht.

Diese Struktur bietet besonders bei der separaten Veröffentlichung von Komponenten Vorteile. So kann beispielsweise ein Bugfix in „component1“ ausgerollt werden, ohne das gesamte Projekt neu veröffentlichen zu müssen. Die CI/CD-Pipelines solcher Projekte sind speziell für diese Struktur ausgelegt. Eine geplante Migration von SVN zu Git stellt das Projektteam dann vor eine Herausforderung. Sie müssen die Struktur in Git abbilden, ohne hohe Kosten für den Umbau des Projekts und der CI/CD-Pipelines zu verursachen.
Eine einfache Lösung ist, die Module als separate Repositories zu pflegen, doch das ist schlecht skalierbar. Wenn ein Projekt mehrere hundert Module umfasst, muss eine gemeinsame Verwaltung in irgendeiner Form möglich sein.
Git bietet zwei Tools, die dieses Problem lösen können: Git Submodules und Git Subtree. Diese Tools beschreiben die Git Entwickler zwar nicht direkt als Hilfsmittel für modulare Repositories. Beide stellen aber die notwendigen Funktionen bereit, um die modulare Struktur beizubehalten und eine gemeinsame Verwaltung zu ermöglichen.
Sowohl Git Submodules als auch Git Subtree basieren auf eigenständigen Repositories für jedes Modul. Die unabhängigen Repositories ermöglichen es den Entwicklern, die Vorteile des modulbasierten Veröffentlichens zu nutzen.
Unterschiede Submodules und Subtree
Auf den ersten Blick scheinen sich die Tools sehr ähnlich zu sein, es gibt jedoch grundlegende Unterschiede, vor allem in der Handhabung. So zeichnet sich Git Subtree dadurch aus, dass das übergeordnete Repository den gesamten Code der module enthält. Somit funktioniert das Repository im täglichen Gebrauch wie ein normales Git Repository. Im Gegensatz dazu speichert Git Submodules nur eine Referenz auf die Repositories der einzelnen Module, was die Entwicklenden bei ihrer täglichen Arbeit berücksichtigen müssen. Dabei liegt lokal zwar der Code der Repositories unter dem übergeordneten Repository jedoch sind im Remote Repository nur die Referenzen der Modul Repositories enthalten.
Die notwendigen Befehle finden sich in der Git-Dokumentation oder in vielen anderen Quellen. Der größte Unterschied in der Bedienung besteht darin, dass bei Git Subtree die Änderungen in das übergeordnete Repository committet werden und die einzelnen Module bei Bedarf synchronisiert werden. Während bei Git Submodules die Änderungen in die Modul Repositories eingecheckt werden und nur die Commit Referenz im übergeordneten Repository aktualisiert wird. Für den Betrieb bedeutet dies, dass man mit Git Subtree in seinem Repository Branches vom übergeordneten Repository erstellen muss, die dann alle Module enthalten. Mit Git Submodules ist dies nicht möglich, hier muss man für jedes Modul eigene Branches angelegen. Je nach Projektumgebung und gewählter Arbeitsweise kann es vorteilhafter sein, das gesamte Repository zu branchen oder nur einzelne Branches anzulegen.
Drittanbieter Lösungen
Neben den Git nativen Ansätzen gibt es auch externe Lösungen. Zum Beispiel Git X-Modules von TMate Software. Diese Lösung ist jedoch kostenpflichtig und basiert auf externen Servern, was je nach Projekt ein Ausschlusskriterium sein kann.
Monorepo
In einem Monorepository befinden sich alle Module direkt unter einem Repository, ohne dass für jedes Modul ein eigenes Repository existiert. Dieser Ansatz hat den großen Vorteil, dass kein Overhead durch den Einsatz zusätzlicher Tools entsteht. Beim Neuaufbau eines Projekts oder bei der Möglichkeit, die CI/CD-Strukturen und den Releaseprozess wirtschaftlich zu überarbeiten, stellt dies in den meisten Fällen die beste Lösung dar.



