Von der Team Foundation Version Control zu Git
Was ist Git?
Git ist – im Gegensatz zur Team Foundation Version Control – ein verteiltes Versionskontrollsystem. Hierbei enthält der einzelne Entwickler-Workspace nicht nur einen Stand des Codes, sondern eine vollständige Kopie des Repositories, die von Zeit zu Zeit mit dem gemeinsamen Stand synchronisiert wird.
Diese Kopie wird durch das Klonen eines gemeinsamen Repositories erstellt. Dadurch ist die Offline-Arbeit vollumfänglich möglich; erst wenn der Stand den Kollegen im gemeinsamen Repository zur Verfügung gestellt werden soll, ist eine Verbindung zum Server selbstverständlich notwendig.
Warum wechseln?
Einerseits wird häufig remote entwickelt, wobei dieses Szenario von einem zentralisierten Versionskontrollsystem wie der Team Foundation Version Control (TFVC) nur eingeschränkt unterstützt wird.
Andererseits kann jedes TFS Team Projekt nur ein TFVC Repository enthalten. In der Regel wird jedoch ein Team Projekt pro Team aufgesetzt, auch wenn dieses an verschiedenen (Teil-)Produkten arbeitet. Dies ist aus Sicht des Work Item Trackings auch sinnvoll, weil der Gesamtüberblick über die Arbeit früher oder später auf Team-Ebene zusammengefasst wird. Aus der Perspektive der Quelltextverwaltung führt dieser Ansatz jedoch gerade bei einer größeren Produktlandschaft dazu, dass die eine Verzeichnishierarchie, die die TFVC bietet, früher oder später sehr unübersichtlich wird.
Da für ein TFS Team Projekt mehrere Git-Repositories angelegt werden können, kann die Code-Ablage unabhängig von den Work Items stattfinden. So können separate Repositories für die Projekte angelegt werden. Ein Entwickler, der nur mit einem Projekt arbeitet, kann das entsprechende Repository klonen und muss sich nicht in der komplexen Verzeichnishierarchie zurechtfinden, nur um zum relevanten Projekt zu gelangen.
Auch der Ansatz des Branchings in Git ist deutlich einfacher als beim TFS. In der TFVC werden Branches auf Verzeichnisebene abgebildet. So sind normalerweise alle Branches für alle Entwickler verfügbar. In Git können Branches auch nur im lokalen Repository angelegt werden, so dass private Branches verwendet werden können. Dadurch, dass die Erstellung eines Branches in Git auch sehr einfach geht, werden Branches in Git deutlich häufiger genutzt.
Mittlerweile empfiehlt Microsoft, dass bei neuen Team Projekten direkt auf Git gesetzt werden sollte, sofern kein Grund für eine zentralisierte Versionskontrolle besteht. Ein detaillierter Vergleich ist unter folgendem Link zu finden. Wenn man bereits ein Team Projekt mit einem TFVC-Repository hat, kann man trotzdem neue Git-Repositories hinzufügen, so dass auch ein schleichender Übergang möglich ist.
Migration von TFVC zu Git
Die Migration von einem TFVC-Repository hin zu mehreren Git-Repositories ist auf mehrere Wege möglich. Besonders einfach ist diese natürlich, wenn man auf die Historie verzichten kann. In diesem Fall reicht es, ein oder mehrere neue Git-Repositories anzulegen und den aktuellen Stand in diesen aufzunehmen.
Soll die Historie beibehalten bleiben, leistet das Tool git-tfs gute Dienste. Dieses erlaubt das Klonen eines TFVC-Repositories in ein Git-Repository. Dieser Klon kann später mit den neuesten Änderungen aus der TFVC aktualisiert werden. So kann man zeitweise parallel arbeiten, sofern dies notwendig ist. Soll neben der Historie auch die Zuordnung der Work Items zu den Commits erhalten bleiben, ist es notwendig, ein neues Team Projekt mit Git aufzusetzen.
Vorbereitung der Migration
Insbesondere bei größeren Repositories sollte man den Migrationsvorgang gut vorbereiten. Normalerweise wird bei der Migration nicht nur ein neues Git-Repository erstellt, sondern mehrere. Daher sollte die Struktur des bestehenden TFVC-Repositories gut untersucht und die Git-Zielrepositories geplant werden.
Besondere Beachtung verdienen an dieser Stelle geteilte Inhalte. In der TFVC sind die Projekte ja notgedrungen in der gleichen Verzeichnishierarchie enthalten. So ist der Zugriff auf geteilte Inhalte möglich, indem man im einfachsten Fall direkt auf die geteilten Inhalte in anderen Verzeichnissen zugreift oder diese per Branch in das Projekt übernimmt. Bei der Aufteilung in separate Git-Repositories werden die geteilten Inhalte in einem separaten Repository abgelegt und dieses per Submodule oder Subtree in ein anderes Repository eingebunden.
Üblicherweise vermeidet man es, in Git-Repositories größere Mengen binärer Dateien abzulegen, insbesondere, wenn diese sich häufig ändern. Da auf dem Entwickler-Rechner die gesamte Historie abgelegt wird, vervielfacht sich in diesem Fall einerseits der Speicherplatz und andererseits auch die Zeit, in der die Synchronisation mit dem gemeinsamen Repository vorgenommen werden kann.
Insofern sollten die Projekte möglichst so gestaltet werden, dass die notwendigen Binaries nicht in der Quelltextverwaltung abgelegt werden müssen. Nuget bietet mit dem Package Restore eine gute Möglichkeit, um den packages-Ordner beim Build neu zu füllen, anstatt diesen in das Repository aufzunehmen.
Auch der Umgang mit Branches ist gut zu prüfen, bevor man die Migration angeht. git-tfs kann TFVC-Branches mit einigen Einschränkungen in Git-Branches umwandeln. Dies ist an folgender Stelle genauer beschrieben.
Der richtige Weg
Die letzten Absätze zeigen, dass die Migration mit der Historie relativ aufwändig sein kann. Insofern ist der einfachste Weg, auf die Historie zu verzichten und den Stand der Projekte nach den Vorbereitungsarbeiten in ein neues Git-Repository zu übernehmen. Dies hat auch den Vorteil, dass keine Spuren von größeren Binaries mehr in den neuen Git-Repositories vorhanden sind und diese dadurch kleiner sind.
Ist der Verzicht auf die Historie nicht möglich, sollte der Ablauf gut geprüft werden, bevor die eigentliche Migration erfolgt. Da das Ausgangsrepository unverändert bleibt, können auch mehrere Anläufe genommen werden, ohne dass die Arbeit des Teams zu stark beeinträchtigt wird. Auf diese Weise können zentrale Vorgehensweisen wie beispielsweise die Arbeit mit dem neuen Repository oder der Build schon vorab getestet werden, damit die Migration ein Erfolg wird.
Wir konnten mit dieser Vorgehensweise unsere TFVC-Repositories, die mittlerweile auch einige Jahre und Projekte gesehen haben, ohne Probleme auf Git umziehen.