Die Team Foundation Version Control bietet die Möglichkeit, Source Code zu branchen. Damit kann man z.B. Hotfixes für ausgelieferte Versionen der Applikation auf dem sogenannten Wartungs-Branch entwickeln, während bereits neue Funktionalitäten auf dem Entwicklungs-Branch eingebaut werden. Mit Hilfe der Merge-Operation können Änderungen an einem der Branches zu einem anderen übertragen werden. Dabei gibt es die Option alle Änderungen bis zu einer bestimmten Revision des Branches oder aber nur ausgewählte Änderungen zu übernehmen. Dabei kommt es evtl. zu unerwarteten Effekten, auf die wir hinweisen möchten.
In unserem Beispiel wurde Code in eine Datei hinzugefügt.
Änderung 183 enthält die Methode namens A, Änderung 184 die Methode B und 185 die Methode C.
Wir wollen nun 2 Szenarien durchspielen. Zunächst soll nur die Änderung 184 in den Wartungs-Branch übertragen werden. Dabei hilft uns der Merge-Wizard, der bei Auswahl der Option "Selected Changesets" alle noch nicht "gemergten" Änderungen auflistet.
Wir wählen lediglich die Änderung 184 – Operation B. Nach dem Klick auf "Finish" wird kräftig gemischt und wir erhalten als Ergebnis folgende Darstellung im Merge-Tool:
Auf der linken oberen Seite ist die Server-Version dargestellt und zwar in der Revision 184, dem Zeitpunkt an dem Operation B hinzugefügt wurde. Es wird richtig erkannt, dass in der Zieldatei des Wartungs-Branches die Operation A nicht auftauchen soll (rechts in rot). Das Merge-Ergebnis (unten) entspricht damit unseren Erwartungen.
Doch drehen wir diesen Merge noch einmal zurück und fangen neu an.
Im zweiten Szenario soll lediglich die Änderung 185 übertragen werden, in der Operation C hinzukam.
Das Ergebnis im Merge-Tool entspricht diesmal nicht ganz unseren Erwartungen:
Das Ergebnis enthält die Operation A. Dies ist von uns aber nicht gewollt. Im rechten oberen Teil des Merge-Tool ist zu sehen, dass Methode A rot markiert ist – also als Deleted Text in der Zieldatei gehandelt wird. Leider bringt hier auch ein auswählen dieser Änderungen das Merge-Tool nicht dazu, die Zeile aus dem Merge-Ergebnis (unten) zu entfernen. Schade – denn das würde dann genau dem erwarteten Ergebnis entsprechen. Stattdessen müssen wir jetzt von Hand diese Änderung vornehmen – bekommen also nur visuelle Unterstützung. Es scheint also, als würden zusammenhängende Codeblöcke nicht aufteilbar sein, wenn es ans Mergen geht.
Wie kann man das umgehen, wenn man darauf angewiesen ist, feingranular Änderungen zu mergen?
Eine Möglichkeit ist die Verwendung von Partial Classes – also die Aufteilung einer Klasse auf mehrere Dateien. Das hat zudem den Vorteil, dass die parallele Entwicklung mit weniger Konflikten von statten geht. Es macht vor allem Sinn, wenn mehrere Interfaces implementiert werden. Diese Implementierungen sollten je Interface in eine Partial Class aufgesplittet werden. So lassen sich z.B. Interface-Änderungen besser in den Griff bekommen.