Git und die Team Foundation

Letzte Änderung am 28. Dezember 2021 by Christoph Jüngling

Dass Git als dezentrale Quellcodeverwaltung (Versionsverwaltung) mit TFVC (Team Foundation Version Control) als zentralistischem Ansatz zusammenarbeiten sollte, das erscheint genauso widersinnig wie Git und SVN – oder genauso sinnvoll, je nach Blickwinkel. Aufgrund eines aktuellen Projektes musste ich mich ein wenig mit TFVC beschäftigen, und habe dabei natürlich unter anderem auch nach einer Möglichkeit gesucht, lokal trotzdem weiterhin mit Git zu arbeiten. Spoiler: So schlimm ist es gar nicht.

Das geht übrigens im Prinzip auch mit Subversion!

Grundsätzliches

Die Frage, ob eine Versionsverwaltung zentral oder dezentral ist (sein sollte), kann man schon als eine Grundsatzfrage ansehen. Ich kann das wohl auch nicht abschließend entscheiden, habe aber was mich betrifft eine ziemlich klare Meinung dazu. In diesem Artikel will ich auch ein wenig darauf eingehen, warum ich Git bevorzuge.

Grundsätzlich bedeutet zentral (wie z.B. SVN oder TFVC) in diesem Zusammenhang, dass es einen Single Point of Information gibt. Dies ist der entsprechende Server, in dem das “Repository” liegt. Der Client (also die Software auf deinem Rechner) tauscht mit dem Server Informationen aus, wann immer du etwas von dem Repository willst: Einchecken, auschecken oder einfach nur im Log nach etwas suchen.

Verteilt oder dezentral (wie z.B. Git und Hg) wiederum bedeutet, dass es nicht nur ein Repository gibt, sondern beliebig viele. Jedes einzelne enthält dabei alle Informationen, also auch die komplette Historie. Dadurch kann man lokal vieles ohne Netzwerkverbindung machen, was bei einem zentralen System immer eine Interaktion mit dem Server erfordert. Nur manche Aktionen erfordern auch bei einem dezentralen System eine Serververbindung.

Motivation für Git

Sicher kann man sich fragen, wieso es denn unbedingt immer Git sein muss. Das mag auch durchaus jeder für sich entscheiden. Ich habe mit Kollegen gesprochen, die Quellcodeverwaltung eher als notwendiges Übel betrachten, das man macht, weil der Chef oder das Team es so will. Andere sagen, sie “verwenden keine Quellcodeverwaltung, das ist nur was für große Projekte”. Ich sehe das anders, wie ich bereits oft in diesem Blog dargelegt habe – die eigene Kategorie Quellcodeverwaltung spricht Bände, denke ich.

Für mich also ist es klar: “Nie mehr ohne!” Und ich will Git, weil die Möglichkeiten vor dem Hochladen meiner Software auf den Server sehr vielfältig sind. (Gleiches natürlich für Mercurial und andere dezentrale Systeme, aber davon habe ich mich vor einiger Zeit bereits getrennt.) Mir geht es nicht nur um die Archivierung der Arbeitsergebnisse, sondern auch um die Dokumentation des Weges dahin und die Verlinkung mit dem Bugtracking-System. Beides bietet TFVC zwar auch sehr schön mit dem Team Explorer allein, aber dann würde entweder jeder Checkin sofort auf dem Server landen, oder ich müsste warten bis ich fertig bin und dann alle Änderungen in einem Checkin hochladen. Ersteres würde den Kollegen unter Umständen unfertige Arbeitsergebnisse bereitstellen und einen automatischen Build fehlschlagen lassen, letzteres wäre im Nachgang unübersichtlich, wenn man mal einen Fehler suchen muss.

Git – auch wenn ich es nur lokal verwenden kann – erlaubt mir, beides zu tun: Permanent lokal (!) einchecken (committen), was ich für nötig halte, Änderungen daran auch nachträglich noch machen können, und dann erst hochladen wenn ich fertig bin.

Tools und deren Installation

Git und TortoiseGit

Wer mit Git arbeiten will, muss Git installieren. Das klingt trivial (und ist es im Grunde auch), daher hier nur der Link für den Download von Git für Windows. Bitte such dir die passende Bitbreite für dein System heraus, wenn das nicht durch JavaScript beim Aufruf der Seite automatisch erledigt wurde. Eine Anleitung für die Installation und den ersten Start habe ich ebenfalls bereits veröffentlicht.

TortoiseGit muss nicht zwingend installiert werden, es ist aber sehr praktisch, weil es die Bedienung von Git auf der graphischen Oberfläche ermöglicht. Download hier, Anleitung siehe vorherigen Link.

Microsoft Team Explorer

Die Namen sind immer witzig, oder? Ein “Team-Erforscher” von Microsoft erforscht keineswegs das Team, hier ist wohl die Übersetzung “Erkunder” passender. Allerdings erkundet diese Software wiederum nicht das Team, sondern das Repository auf dem Team Foundation Server (TFS).

Dies ist für Git eigentlich nicht unbedingt erforderlich, aber wenn man spezielle Dinge auf dem zentralen Repository machen will, brauchen wir den. Außerdem bringt die Installation den dringend benötigten Treiber für den TFS mit, den wir dann im nächsten Schritt brauchen. Download hier.

git-tfs

Das Tool git-tfs (Projekt auf Github) stellt quasi die Brücke zwischen Git und dem TFS dar. Es ergänzt Git um den Sub-Befehl “tfs”. Dies ähnelt der Anbindung an SVN, die in Git vom Start weg vorhanden ist. Soweit ich mich erinnere, muss man hier nichts besonderes machen, außer halt runterladen und installieren.

In der Praxis

Anders als die bereits erwähnte SVN-Integration in Git bietet git-tfs nur ein paar zusätzliche Befehle für die Kommandozeile an. TortoiseGit merkt davon leider nichts, so dass man bei jeder Interaktion mit dem Team Foundation Server auf die Konsole angewiesen ist. Das ist nicht so schwer zu lernen, aber für die Mäuseschubser unter uns habe ich gleich noch ein paar Vorschläge zu machen.

Klonen des Projektes

Bei Git beginnt alles mit dem Klonen eines Projektes (es sei denn man arbeitet nur lokal). Für ein TFS-System lautet der Kommandozeilenbefehl:

git tfs clone REPOSITORY PROJECT_PATH LOCAL_PATH
git tfs clone https://my.server.com/projectname $/path/in/project local-folder-name

Man beachte die Trennung zwischen der URL des Repositories (hier “https://my.server.com/projectname”) und dem Pfad innerhalb dessen (hier “$/path/in/project”), der unbedingt mit “$/” beginnen muss. Der letzte Parameter bezeichnet das neu zu erstellende lokale Verzeichnis. Dort wird dann das lokale Git-Repository mit Arbeitsverzeichnis angelegt. Wie bei Git üblich erfolgt nach erfolgreichem Clone sofort ein Checkout auf den master-Branch (das ist hier der Branch, den ich zuvor als Project-Path angegeben habe).

Falls das Projekt im TFVC über Branches verfügt, können diese ebenfalls in Git dargestellt werden. Dazu muss der Befehl nur um einen Zusatz erweitert werden:

git tfs clone --branches=all REPOSITORY PROJECT_PATH LOCAL_PATH

Bitte dabei nicht ungeduldig werden, auch bei kleinen Projekten kann das schon mal einige Minuten dauern. Immerhin muss man dies ja nur einmal zu Beginn der Arbeiten machen, dann hat Git alles lokal vorrätig, was gebraucht wird.

Abholen des aktuellen Standes

Nicht nur in Git ist es üblich, sich ab und zu mal die Ergänzungen zu beschaffen, die die Kollegen bereits auf den Server geladen haben. Was in Git mit git pull gemacht wird (oder besser in TortoiseGit), muss auch bei TFS auf der Konsole erfolgen, ist aber fast genau so einfach:

git tfs pull

Dieser Befehl lädt alle neuen Änderungen im aktuellen Branch vom Server in das lokale Git-Repository und aktualisiert das Arbeitsverzeichnis dementsprechend. Allerdings geht ein “Pull” (auch bei Git allein) nur gut, wenn ich keine lokalen Commits habe, die noch nicht auf dem Server gelandet sind. Daher ist die Ergänzung um --rebase durchaus sinnvoll. Dieser Befehl aktualisiert Repository und Arbeitsverzeichnis wie zuvor beschrieben und setzt dann meine lokalen Commits auf den erweiterten Zweig oben darauf. So entsteht wieder eine lineare Historie, und falls es keine Konflikte gab, ist alles in Ordnung.

Eine weitere sinnvolle Ergänzung ist --with-labels, wodurch Labels (Git nennt das “tags”) vom TFVC ebenfalls herunter geladen werden. Damit kann ich dann in Git fast so arbeiten wie ich es gewöhnt bin. Siehe auch das Kapitel “Einschränkungen” weiter unten im Text.

git tfs pull --with-labels --rebase

Eine zweite Möglichkeit (auch bei Git allein) ist der “Fetch”. Dieser lädt die Änderungen vom Server nur in das lokale Repository, lässt jedoch das Arbeitsverzeichnis in Ruhe. Das ist nicht besser oder schlechter als ein “Pull”, nur anders. Kommt halt drauf an, was man braucht.

Zusätzlich hole ich mir dann noch die neuen Labels ab, was einen zweiten Befehl erfordert:

git tfs fetch --all --branches=all
git tfs labels

Abliefern der Arbeitsergebnisse

Die dritte Vorgehensweise betrifft die gegenteilige Richtung, denn irgendwann muss ich ja meine Ergebnisse mal auf den Server laden. Bei Git würde ich das mit git push machen (oder halt mit ein paar Klicks in TortoiseGit), mit TFS ist das einer der folgenden Befehle:

git tfs checkin
git tfs rcheckin

Der Befehl “checkin” bündelt alle meine Commits in einem einzigen Changeset und schiebt diese auf den TFS, während “rcheckin” die Commitstruktur unverändert lässt, also für jeden Commit ein eigenes Changeset im TFS anlegt. Ich bevorzuge “rcheckin”, weil ich ganz bewusst verschiedene Commits erzeuge (zum Beispiel um ein Refactoring von der inhaltlich relevanten Änderung zu trennen).

Gleichzeitig wird dabei das lokale Git-Log noch um ein paar Informationen erweitert:

  • An die Commit-Message wird die Information des Changesets angehängt (Pfad und Nummer)
  • Via Git-Notes wird eine eventuelle Verknüpfung mit einem Workitem (Nummer, Titel und Link) angehängt

Tricks

Bei lokalen Commits ist es in Git durchaus üblich, etwas mehr zu schreiben, damit ich auch später noch weiß, was ich gemacht habe, und warum. Das geht natürlich auch in Verbindung mit dem TFVC, die Commit-Message wird diesem vollständig bereitgestellt.

Zusätzlich kann ich mit der Schreibweise “#1234” aber auch Workitems direkt verlinken lassen. Dies erfolgt dann in der gleichen Weise, als ob ich dies im TFVC manuell gemacht hätte, und natürlich lässt sich das nachträglich auch noch ändern, also ergänzen oder bereits verlinkte Items wieder herausnehmen.

Einschränkungen

Git kann vieles, aber in Zusammenarbeit mit TFVC darf man einiges leider nicht benutzen.

  • Tags können nicht gepusht werden, aber auf dem TFVC vorhandene Labels werden (wenn angegeben) in Git in bekannter Weise angezeigt und sind normal verwendbar
  • Neue Branches gehen nur lokal (auch deren Löschung), müssen aber vor dem rcheckin mittels Git-Rebase auf den Arbeitsbranch aufgesetzt werden. Auf bereits im TFVC existierenden Branches kann jedoch ganz normal gearbeitet werden.

Erleichterungen

Und hier noch die versprochenen Erleichterungen für die Mäuseschubser :-)

Die oben dargestellten Kommandozeilenbefehle sind zwar nicht unbedingt schwer zu merken, aber sie jedes mal eintippen? “Kann man machen, muss man aber nicht.” (Rüdiger Hoffmann) Daher habe ich mir ein paar .cmd-Files angelegt, die ich im Download-Bereich bereitstelle.

Diese können gern in jedes Arbeitsverzeichnis hinein kopiert werden, meinetwegen auch im Repository landen. Ich persönlich ziehe jedoch auch hierbei das Prinzip vor, Code nur einmal zu schreiben und abzulegen (DRY). Daher sind diese Dateien bei mir in einem zentralen Verzeichnis.

Damit sie im Projekt leicht ausführbar sind, erstelle ich mir in dem Projektordner jeweils eine Windows-Verknüpfung zu den drei Dateien. Dabei muss ich nur darauf achten, dass ich die Einstellung “ausführen in” auf das Verzeichnis des Projektes setze.

Ferner benenne ich die Verknüpfungen um und lasse sie mit einem “_” beginnen, damit sie bei alphabetischer Sortierung immer am Anfang des Verzeichnisses stehen. Nun reicht ein Doppelklick auf die jeweilige Datei (und etwas Geduld).

Tja, das war’s dann also. Falls mir noch etwas dazu einfällt, werde ich das später noch ergänzen. Und falls ihr Rückfragen habt, nutzt gern die Kommentarfunktion oder schreibt mir eine eMail.

Ähnliche Artikel:

Schreibe einen Kommentar

Deine Email-Adresse wird nicht veröffentlicht.

zwölf + 15 =