18. Feb 2019
Lesedauer 15 Min.
Der TFS im Wandel der Zeit
Von Team Foundation Version Control (TFVC) nach Git
Eine Umstellung der Quellenverwaltung hin zu Git ist schnell erledigt. Doch gelingt die Umstellung für das Entwicklungsteam ebenso schnell?

Git hat mit seiner dezentralen Architektur sowie seiner Branching- und Merging-Strategie anderen Quellenverwaltungssystemen wie etwa CVS, SVN oder Team Foundation Version Control (TFVC) schon lange den Rang abgelaufen [1]. Das hat auch Microsoft erkannt und führte Git 2013 zunächst in Visual Studio Team Services (heute Azure DevOps) ein und kurze Zeit später auch in die On-Premises-Lösung Team Foundation Server 2013. Auch auf Entwicklerseite ist seit Visual Studio 2013 eine native Git-Unterstützung vorhanden. Seither residieren TFVC und Git parallel im TFS und der Anwender kann sich beim Aufsetzen eines neuen Teamprojekts für eines der beiden Systeme entscheiden. Grundlegendes zu deren Unterschieden finden Sie auch im Kasten Verteilte oder zentralisierte Quellenverwaltung.Für die folgenden Betrachtungen spielt es keine entscheidende Rolle, ob Microsofts Azure DevOps und der Team Foundation Server (TFS) eingesetzt werden, weshalb für den Rest des Artikels ganz allgemein vom TFS gesprochen wird.
Verteilte oder zentralisierte Quellenverwaltung
Systeme zur Verwaltung von Entwicklungsquellen gibt es bereits seit über 40 Jahren. Sie lassen sich heute grob in zwei Kategorien unterteilen: zentralisierte und verteilte Systeme.
Betrachtet man die entsprechenden Release Notes der vergangenen Jahre näher, so nimmt man bei Microsoft einen deutlich stärkeren Fokus auf Git denn auf TFVC wahr. Neue Features für TFVC sind in den jüngsten Versionen kaum mehr enthalten, was viele Entwicklungsteams unweigerlich zu der Frage führt, wie lange TFVC noch unterstützt wird.Damit ein Umstieg vom klassischen TFVC hin zu Git unter Verwendung des Team Foundation Servers oder Azure DevOps mit minimalen Geschwindigkeitseinbußen des Teams gelingt, zeigt der vorliegende Artikel, wie eine Migration ablaufen könnte und wie im Team etablierte Routineaufgaben mit Git zu lösen sind.
Migrieren nach Git
Unabhängig davon, ob der Team Foundation Server als On-Premises-Lösung direkt im Unternehmen eingesetzt wird oder ob Microsofts Azure-DevOps-Plattform Verwendung findet, besteht die Migration eines Teamprojekts nach Git aus den folgenden Schritten:- Neues Teamprojekt erstellen
- Migration des Repositorys
- Migration der Backlog Items
- Build-Definitionen anpassen

Ein neues Teamprojekterstellen(Bild 1)
Autor
Im zweiten Schritt geht es nun daran, die vorhandenen Quellen samt Versionshistorie und Branches in das soeben erstellte Git-Repository zu migrieren. Hier gibt es mehrere Möglichkeiten, die abhängig von Größe und Inhalt des TFVC-Repositorys mehr oder weniger gut geeignet sind. Der TFS stellt für den Import kleinerer Projekte das TFVC Import Tool [2] zur Verfügung. Es hat zahlreiche Limitierungen wie etwa die Beschränkung auf nur einen Branch und eine maximal migrierbare Versionshistorie von 180 Tagen, weswegen es für die wenigsten professionellen Projekte einen gangbaren Weg darstellen wird.Eine bessere Alternative ist das Kommandozeilen-Tool git-tfs. Es versteht sich als Brücke, um TFVC-Repositories von und nach Git-Repositories zu synchronisieren. Die Quellen des Tools sind auf GitHub zu finden und die Versionshistorie lässt auf ein aktiv gepflegtes Projekt schließen. In diesem Szenario genügt eine einmalige Migration.Sowohl das TFVC Import Tool als auch git-tfs migrieren lediglich die Projektquellen. Backlog Items wie Features, Stories et cetera und andere Einstellungen des ursprünglichen Teamprojekts bleiben unberücksichtigt.Um mit git-tfs zu starten, lädt man sich die neueste Version von der Projektwebseite [3] auf den eigenen Entwicklungsrechner, entpackt das erhaltene Archiv in einen beliebigen Ordner und fügt den Ordnernamen der Path-Umgebungsvariablen hinzu. Letzterer Schritt vereinfacht die Arbeit mit der Kommandozeile. Weitere Voraussetzungen sind ein installiertes Git und Visual Studio ab Version 2013.Für die Migration öffnet man zunächst die Windows-Kommandozeile (oder PowerShell). Mit dem Befehl
<span class="hljs-string">git </span><span class="hljs-string">tfs </span><span class="hljs-built_in">list-remote-branches</span> <span class="hljs-string">http:</span>//<span class="hljs-string">tfs:8080/</span><span class="hljs-string">tfs/</span>
<span class="hljs-string">DefaultCollection </span>
listet man alle erreichbaren Projekte (und deren Branches) des angegebenen TFS und der angegebenen Collection auf, die auf einem TFVC-Repository basieren. Protokoll (HTTP oder HTTPS), Servername und Collection müssen an die jeweilige Umgebung angepasst werden.Folgender Befehl startet den eigentlichen Migrationsvorgang:
git tfs <span class="hljs-keyword">clone</span> <span class="hljs-title">http</span>://tfs:<span class="hljs-number">8080</span>/tfs/
DefaultCollection $/some-project
Hierbei wird zunächst im aktuellen Ordner ein leeres Git-Repository erstellt und es werden nacheinander alle Check-ins vom TFVC-Repository abgerufen und in das Git-Repository übertragen (Commit). Dies umfasst den ausgewählten Branch und dessen abhängige Branches. Abhängig von der Komplexität der Check-ins und deren Anzahl kann dieser Vorgang von einigen Minuten bis hin zu mehreren Stunden dauern. Es gibt eine Reihe weiterer Applikationsschalter, über die sich der Vorgang anpassen lässt.Nach Abschluss des Vorgangs muss das lokale Git-Repository nun zum zentralen TFS-Repository hochgeladen werden. Dafür registriert man das Git-Repository des TFS als sogenanntes Remote Repository im lokalen Repository. Ein Remote Repository wird lokal durch einen Namen identifiziert, wobei sich origin als Standardname für das primäre Remote Repository etabliert hat:
git remote add origin http:<span class="hljs-regexp">//</span>tfs:<span class="hljs-number">8080</span><span class="hljs-regexp">/tfs/</span>
DefaultCollection<span class="hljs-regexp">/git/</span>ToolLink
Folgender Befehl überträgt nun das lokale Git-Repository vollständig zum TFS:
git <span class="hljs-built_in">push</span> -u <span class="hljs-built_in">origin</span> –all
Branching-Strategie
Nach erfolgter Migration des Teamprojekts sind vor Beginn der Arbeit mit dem neuen Git-Repository einige grundlegende Dinge zu überdenken. Eines davon ist die etablierte Branching-Strategie.Branches in TFVC-Repositories sind etwas „Schweres“ und kein leichtgewichtiges Mittel wie bei Git. Der Grund dafür ist, dass beim Erstellen eines Branchs in TFVC-Repositories eine vollständige Kopie der Daten des Quellbranchs erstellt wird, welche die Ausgangsbasis für zukünftige Änderungen auf dem neuen Branch darstellen. Die Branch-Erstellung kann daher – abhängig von der Größe des Quell-Branchs – recht lange dauern und kostet relativ viel Speicherplatz im Repository. Studiert man die von Microsoft vorgeschlagenen Branching-Strategien für TFVC-Repositories, so lässt sich feststellen, dass sie eher zur Isolierung langlebiger Entwicklungszweige wie beispielsweise zur Stabilisierung freigegebener Versionen verwendet werden sollten.Git geht hier einen anderen Weg. Einfach ausgedrückt stellt ein Branch lediglich einen Zeiger auf einen bestimmten Commit dar. Das funktioniert, weil anders als bei Check-ins in TFVC-Repositories ein Commit einen vollständigen Snapshot der Projektquellen beschreibt. Das Erstellen von Branches ist dadurch so effizient, dass es zur Isolierung jeglicher Arbeiten an der Codebasis eingesetzt werden kann.Hier gibt es die erste grundlegende Änderung für die Arbeitsweise der Entwickler im Team: Änderungen an der Codebasis werden zunächst auf einem sogenannten Feature-Branch durchgeführt, ehe man sie mittels Pull Request in einen der Hauptentwicklungszweige überführt.Änderungsverfolgung
Weiterhin gibt es einen fundamentalen Unterschied beim Tracking der Dateien. Während beim TFVC Dateien explizit zur Quellenverwaltung hinzugefügt werden müssen, funktioniert Git genau andersherum. Alle Dateien, die nicht explizit ignoriert werden sollen, landen im Zuge eines Commits in der Quellenverwaltung. Beim ersten Commit nach einer Migration kann es also dazu kommen, dass versehentlich sämtliche lokalen Build-Ordner wie \obj oder \bin in der Quellenverwaltung landen. Die Lösung dafür ist die sogenannte .gitignore-Datei. Sie residiert im Root-Ordner des Repositorys und definiert, welche Dateien und Unterordner nicht in der Quellenverwaltung landen sollen. Unter [4] gibt es eine Sammlung solcher Dateien für die verschiedensten Entwicklungsumgebungen. Visual Studio bietet im Team Explorer unter Settings | Repository Settings die Möglichkeit, die aktuell konfigurierte Datei zu bearbeiten oder eine initiale Datei hinzuzufügen.An die Arbeit
Für das Erstellen des Feature-Branchs für ein zu entwickelndes Feature oder einen Bugfix gibt es mehrere Möglichkeiten. Nutzt das Team den TFS auch zur Planung und Dokumentation seines agilen Vorgehens (Stichwort Scrum oder Kanban), kann ein Branch in der Backlog-Ansicht für ein konkretes Backlog Item (User Story, Task et cetera) erstellt werden. Dafür fährt man mit der Maus über das Backlog Item und klickt auf die erscheinenden drei Punkte. Daraufhin öffnet sich ein Menü, das den Eintrag zum Erzeugen eines neuen Branchs enthält. Zur Abfrage des Branch-Namens und weiterer Details erscheint dann ein Dialog wie in Bild 2.
Einen Branch erstellenmittels TFS Web GUI(Bild 2)
Autor
Der über diesen Weg erstellte Branch ist automatisch mit dem zuvor ausgewählten Backlog Item verknüpft, was im Hinblick auf die Nachverfolgbarkeit von Änderungen vorteilhaft ist. Die Option Based on beschreibt den Quell-Branch und enthält standardmäßig den Branch, der in den Teamprojekt-Einstellungen als Standard-Branch festgelegt ist. Je nach Branching-Strategie ist das meist der master- oder – wenn vorhanden – der dev-Branch. Ein abschließender Klick auf Create branch erstellt den Branch, der sofort für alle Teammitglieder abrufbar ist.Es gibt Situationen, in denen der Zugriff auf den TFS beziehungsweise das zentrale Repository nicht möglich ist. Hier kann Git mit seiner dezentralen Architektur punkten. Statt den Branch über das Web-GUI anzulegen, kann dieser auch initial im lokalen Repository erstellt werden. Hierfür bietet sich der Team Explorer von Visual Studio an. In der Branches-Ansicht findet man den Menüpunkt New Branch. Nach Eingabe eines Namens und der Auswahl des Quell-Branchs kann er durch Bestätigung mittels Create Branch angelegt werden. Unabhängig davon, ob eine Verbindung zum zentralen Repository besteht oder nicht, ist der Branch zunächst nur im lokalen Repository vorhanden. In Visual Studio ist dieser Sachverhalt durch das Fehlen des grünen Pfeils am Symbol vor dem Branch-Namen zu erkennen.Eine dritte und vom Autor bevorzugte Variante ist das Erstellen eines Branchs über die Kommandozeile. Der Befehl
git checkout -<span class="hljs-selector-tag">b</span> <span class="hljs-string">"MyFeature"</span>
erstellt einen neuen Branch, der auf dem aktuellen Branch basiert, und wechselt im Anschluss an die Erstellung in den neu erstellten Branch.Wird der Branch lokal erstellt, gibt es zunächst keine Möglichkeit, ein Backlog Item mit dem Branch zu verknüpfen. Dies muss in einem separaten Schritt erfolgen, wenn der Branch zum zentralen Repository übertragen wird, oder im Zuge des Pull Requests – doch dazu später mehr.Auf dem nun vorhandenen Feature-Branch kann die eigentliche Entwicklungsarbeit beginnen. Änderungen an der Codebasis können sinnvoll in einzelne Commits unterteilt werden. Dabei ist zu beachten, dass ein Commit nicht genauso funktioniert wie ein Check-in im TFVC. Ein Commit legt die Änderungen nur in das lokale Repository ab, wodurch kein anderer Entwickler Zugriff darauf hat.Nach Abschluss aller Arbeiten sollen nun sämtliche Änderungen des Branchs in das zentrale Repository des TFS übertragen werden (push). Hierfür bietet der Team Explorer von Visual Studio in der Synchronization-Ansicht die Möglichkeit, Änderungen des lokalen Repositorys mit den Änderungen des zentralen Repositorys zusammenzuführen. Mit einem Klick auf Pull werden zunächst die Änderungen im TFS in das lokale Repository übernommen. Anschließend können lokale Änderungen durch einen Klick auf Push zum TFS übertragen werden. Mittels der Kommandozeile lassen sich diese beiden Aktionen wie folgt durchführen, wenn der Branch im TFS bereits bekannt ist:
<span class="hljs-symbol">git</span> pull
git <span class="hljs-keyword">push </span>
Andernfalls nutzen Sie dazu
git <span class="hljs-keyword">push</span> --<span class="hljs-keyword">set</span>-upstream origin FeatureBranch
Commit-Historie bereinigen
Legt das Entwicklungsteam großen Wert auf eine gut zu lesende Versionshistorie, sollten Sie vor der finalen Übertragung des Branchs in das zentrale Repository zwei Dinge beachten:Sind in den Quell-Branch (master oder dev) seit der Erstellung des Feature-Branchs keine anderen Commits eingeflossen, kann ein sogenannter Fast-Forward Merge gemacht werden, bei dem der letzte Commit des Feature-Branchs einfach als letzter Commit des Quell-Branchs genutzt wird. Anders sieht es aus, wenn andere Entwickler zwischenzeitlich ihre Änderungen abgeschlossen und in den Hauptentwicklungszweig gemergt haben. Unabhängig davon, ob dabei Konflikte auftreten oder an völlig unterschiedlichen Stellen des Projekts gearbeitet wurde, entsteht beim Zusammenführen zweier Branches oder zweier Versionen desselben Branchs ein sogenannter Merge-Commit (siehe Bild 3). Dieser „verunreinigt“ die Versionshistorie, was eher unerwünscht ist. Diesem Verhalten kann man vorbeugen, indem man vor der Übertragung in das zentrale Repository ein sogenanntes Rebasing durchführt, sodass später ein Merge in den Hauptentwicklungszweig mittels Fast-Forward möglich ist.
Mergingversus Rebasing(Bild 3)
Autor
Die zweite Verbesserung der Versionshistorie erreicht man durch deren nachträgliche Veränderung. Enthält die Commit-Historie des Feature-Branchs beispielsweise Einträge wie Fix recent build failure oder WIP für Zwischendurch-Commits, so möchte man zwar die Inhalte des Commits übernehmen, nicht aber die Commit-Kommentare. Auch hier ist Rebasing – genauer gesagt interaktives Rebasing – des Entwicklers liebstes Werkzeug.Beim einfachen Rebasing werden die Commits des aktuellen Branchs auf einen anderen Ursprungs-Commit angewendet. Dabei wird die Versionshistorie komplett neu geschrieben. Beim interaktiven Rebasing hat man zusätzlich die Möglichkeit, Commits zu bearbeiten, zu entfernen, umzubenennen oder sogar deren Reihenfolge zu verändern. Visual Studio bis Version 2017 unterstützte nur einfaches, nicht aber interaktives Rebasing.Das Rebasing in Visual Studio lässt sich im Team Explorer in der Branches-Ansicht starten. Zunächst stellt man sicher, dass man sich auf dem Branch befindet, auf dem das Rebasing erfolgen soll. Anschließend wählt man mit der rechten Maustaste den Quell-Branch aus, auf dem die Commits des aktuellen Branchs angewendet werden sollen. Im daraufhin erscheinenden Kontextmenü wählt man Rebase Onto … aus und bestätigt noch einmal mit einem Klick auf Rebase. Bei diesem Vorgang können Merge-Konflikte auftreten, die vom Entwickler zu lösen sind. Sind alle Konflikte gelöst, bestätigt man mittels Continue. Durch Abort lässt sich der Vorgang abbrechen und man befindet sich wieder am Ausgangspunkt.Ein interaktives Rebasing bietet mehr Möglichkeiten (siehe weiter oben), erfordert aber auch mehr Aufwand bei der Durchführung. Wer mit der Kommandozeile auf Kriegsfuß steht, kann auf kostenfreie Tools wie Tower oder Sourcetree zurückgreifen.Im Nachfolgenden soll einmal exemplarisch die Durchführung mit der Kommandozeile und Visual Studio demonstriert werden.Bevor es losgehen kann, müssen alle lokalen Änderungen ins Repository committet worden sein. Anschließend erfolgt der Wechsel in den Ursprungs-Branch des Feature-Branchs, um die letzte Version vom zentralen Repository abzurufen:
git checkout <span class="hljs-keyword">master</span>
<span class="hljs-title">git</span> pull
Nun wechselt man zurück auf den Feature-Branch und startet ein interaktives Rebasing:
git checkout FeatureBranch
git rebase -i <span class="hljs-keyword">master</span>
Jetzt öffnet sich wie von Geisterhand der in Git konfigurierte Texteditor mit einer Datei, die eine Auflistung der Commits des Feature-Branchs enthält. Hier hat man nun die Möglichkeit, die Versionshistorie den eigenen Wünschen anzupassen. Die angezeigte Datei enthält auch Erklärungen, wie die Commit-Historie beeinflusst werden kann. Sind alle Anpassungen abgeschlossen, schließt man den Editor und speichert dabei das Dokument.Nun fängt Git an, die Commits des Feature-Branchs auf den letzten Commit des Quell-Branchs anzuwenden. Hier kann es natürlich zu Merge-Konflikten kommen, die vom Entwickler zu lösen sind. Die Ausgabe der Kommandozeile sieht in diesem Fall wie folgt aus:
git rebase <span class="hljs-params">-i</span> master
First, rewinding head <span class="hljs-keyword">to</span> replay your work <span class="hljs-keyword">on</span> top of
it<span class="hljs-params">...</span>
<span class="hljs-params">...</span>
CONFLICT<span class="hljs-params">...</span>
<span class="hljs-params">...</span>
When you have resolved this problem, run <span class="hljs-string">"git </span>
<span class="hljs-string"> rebase –continue"</span>
<span class="hljs-params">...</span>
Hier empfiehlt sich der Wechsel in den Team Explorer von Visual Studio. Das begonnene Rebasing ist auch Visual Studio nicht entgangen, sofern im Team Explorer das aktuelle Git-Repository ausgewählt war, und Visual Studio bietet gegenüber der Kommandozeile komfortablere und dem Entwickler vertrautere Möglichkeiten, die Konflikte zu lösen. Sind alle Konflikte gelöst, gibt man in der Kommandozeile ein:
git rebase –<span class="hljs-keyword">continue</span>
Die Bearbeitung des aktuellen Commits wird so abgeschlossen. Wie beim einfachen Rebasing wird der Vorgang für jeden einzelnen Commit des aktuellen Branchs durchgeführt, weshalb Konflikte gegebenenfalls mehrfach zu lösen sind.Der Lohn nach Abschluss des Vorgangs ist eine saubere Commit-Historie, die zum aktuellen Zeitpunkt konfliktfrei mittels Fast-Forward Merge in den Quell-Branch zurückgeführt werden kann.Da das Rebasing des Feature-Branchs nur das lokale Repository verändert hat, müssen die vorgenommenen Änderungen noch zum TFS übertragen werden (push). Hier ist Vorsicht geboten. Wurden bereits Commits vor dem Rebasing-Vorgang zum TFS übertragen (push), so würde ein erneutes Ausführen eines (einfachen) Push dazu führen, dass die Commits im TFS mit den lokalen Commits gemergt würden. Der TFS weiß ja vom durchgeführten Rebasing nichts und verweist in seiner Version des Feature-Branchs noch auf einen älteren Ursprungs-Commit.Die Lösung ist ganz einfach. An dieser Stelle kann der Feature-Branch des lokalen Repositorys den existierenden Feature-Branch des TFS vollständig überschreiben:
git push <span class="hljs-comment">--force </span>
Jetzt ist auch das zentrale Repository auf dem neuesten Stand und das umgesetzte Feature oder der Bugfix kann in den Hauptentwicklungszweig zurückfließen.
Review und Merge
Um den nun sauberen Feature-Branch in den Quell-Branch zurückzuführen, wird vom Entwickler ein sogenannter Pull Request ausgelöst. Betrachtet man die Begrifflichkeiten des TFVC, so entspricht dieser Vorgang am ehesten einem Code Review, der nach Abschluss mit einem Merge endet.Die Arbeit mit Pull Requests ist ausschließlich über das Web-GUI des TFS möglich. Auf der Teamprojekt-Seite wechselt man zunächst in den Bereich Code und dort in den Unterbereich Pull Requests. Ist der Push-Vorgang noch nicht allzu lange her, unterstützt das Web-GUI des TFS mit einem Hinweis, dass vor Kurzem ein Branch aktualisiert wurde und ein Pull Request erstellt werden kann. Ist dies nicht der Fall, so kommt man auch über die Schaltfläche New Pull Request zur entsprechenden Ansicht, in welcher der Feature-Branch noch ausgewählt werden muss. Neben Titel, Beschreibung und Reviewer sind hier die Work Items anzugeben. Wurde der Branch zu Beginn über das Backlog Item erstellt, ist mindestens dieses bereits mit dem Pull Request verknüpft. Auch die mit den Commits verknüpften Work Items werden mit dem Pull automatisch verknüpft. Im unteren Teil des Pull Requests sieht man noch einmal ein Diff zwischen Feature-Branch und Ziel-Branch. Ein Klick auf die Schaltfläche Create erzeugt den Pull Request.Die Durchführung der Code Reviews im Browser dürften einige Entwickler, die es gewohnt waren, ihre Reviews in Visual Studio vorzunehmen, als gewöhnungsbedürftig empfinden. In Visual Studio hatte man stets die Möglichkeit, die komplette Solution beim Review offen zu haben, und konnte so die Änderungen in Bezug zum umgebenden Code bewerten. Im Web-GUI hingegen sieht man ausschließlich das Diff der gemachten Änderungen.Auch das Zustandsmodell hat sich geändert und bietet nun keine Möglichkeit mehr, dem Initiator des Pull Requests mitzuteilen, dass ein Review in Arbeit ist. Die Kommentierung sorgt ebenfalls für Verwirrungen, wenn eine Codestelle kommentiert wurde und im Zuge der Nacharbeit die entsprechende Codestelle herausgefallen ist. Hier gibt es also noch Raum für Verbesserungen.Auf der anderen Seite sind nachträgliche Änderungen an der Codebasis direkt im Pull Request zu sehen. Ein Pull Request kann damit abgeschlossen werden, wenn der zugrunde liegende Quelltext allen Forderungen der Reviewer genügt. Im TFVC wurde ein bestimmtes Check-in reviewt, weswegen nachfolgende Änderungen einen neuen Code Review benötigten.Haben alle Reviewer grünes Licht gegeben, kann der Pull Request abgeschlossen werden. Hierfür klickt man auf die Schaltfläche Complete. Im daraufhin erscheinenden Dialog gibt es Eingabemöglichkeiten für die finale Commit-Beschreibung und die Entscheidung, ob der Quell-Branch anschließend zu löschen ist. Das ist in aller Regel sinnvoll, da es sich meist nur um einen kurzlebigen Feature-Branch handelt und die Arbeit daran abgeschlossen ist.Und sonst so …
Eine von Entwicklern gern genutzte Funktionalität im Zusammenhang mit TFVC Repositories sind Shelvesets. Sie bieten die Möglichkeit, lokale Änderungen auf dem zentralen Repository „zu parken“, ohne dass die Änderungen im jeweiligen Branch eingecheckt werden müssen. Ein Shelveset ist mit dem Entwickler verknüpft, der das Shelveset angelegt hat, kann aber auch von anderen Entwicklern abgerufen werden.Ein derartiges Konstrukt sucht man in Git-Repositories vergeblich. Als eine entfernte, wenn auch nicht ebenbürtige Alternative kann man das Stashing betrachten. Dabei werden Änderungen im lokalen Repository geparkt, jedoch ohne die Möglichkeit, dass andere Entwickler darauf zugreifen können. Beim Wiederherstellen solcher Stashes werden die Änderungen im Stash mit dem aktuellen Arbeitsstand gemergt, was dem Verhalten eines Unshelve-Kommandos entspricht.Eine weitere Möglichkeit können Branches darstellen. Sie sind schnell erstellt und später auch wieder gelöscht und alle Entwickler im Team haben Zugriff darauf. Man sollte nur darauf achten, einen zu großen Wildwuchs an Branches zu unterbinden, da der Ersteller eines Branchs nicht so leicht zu sehen ist und man schnell den Überblick verlieren kann.Fazit
Die Umstellung der Quellenverwaltung von TFVC hin zu Git und die Beibehaltung des TFS oder Azure DevOps sind technisch heute keine Herausforderungen mehr. In der Praxis erprobte Tools übernehmen die Migration zuverlässig.Dennoch sollte man genügend Zeit für die Migration und die daran anschließende Umstellung der Arbeitsweise des Teams einplanen. Arbeitsweisen und Vorgehen bei der täglichen Arbeit mit dem Sourcecode sollten überdacht und an die neuen Möglichkeiten angepasst werden.Mit den aktuellen Versionen von Visual Studio und dem Team Foundation Server respektive Azure DevOps werden längst nicht alle Features von Git (Interactive Rebase, Forced Push) nativ unterstützt, weshalb man öfter die Entwicklungsumgebung verlassen muss.Fussnoten
- Version Control Systems Popularity (2016), http://www.dotnetpro.de/SL1903TFSGit1
- TFVC Import Tool, http://www.dotnetpro.de/SL1903TFSGit2
- Git/TFS-Bridge git-tfs, https://git-tfs.com
- .gitignore-Templates auf GitHub, https://github.com/github/gitignore
- Git, https://de.atlassian.com/git