Marcus Ross, Einführung und Vorstellung von Git für die tägliche ArbeitEinführung

Wer häufig mit Applikationsentwicklung zu tun hat, kennt das Problem, verschiedene Versionen einer App über den Lebenszyklus zu verwalten. Sie stellen sich Fragen wie „Was habe ich in dieser Datei das letzte Mal verändert?“, „Wir hätten doch die letzte Version nutzen sollen, wo ist die?“ oder „Mist, die App ist kaputt, wie war noch der Stand von heute Morgen?“.

Noch schwieriger wird es, wenn mehrere Entwickler gleichzeitig an einer App arbeiten wollen bzw. müssen. Dann müssen Themen wie „Ich ändere gerade etwas in der Datei xyz, bitte nicht gleichzeitig daran arbeiten“, beachtet werden. Glücklicherweise ist diese Problematik so alt wie die Informatik selbst. Es wird schon immer mit verschiedenen Versionen gearbeitet. Meist nutzen Programmieranfänger den manuellen Weg, wie das Kopieren und Umbenennen einer Datei von „XYZ.dll“ in „XYZ.dll.alt“. Dabei entstehen Bäume wie „XYZ.alt.ganzalt_22012015_vorTicket44“. Spätestens bei dem Entwickeln mit anderen klappt dieser Weg nicht mehr.

Um dem Problem Herr zu werden, gibt es Versionskontroll-Systeme bzw. Version Control Systems. Ein Versionskontroll-System (kurz VCS) arbeitet dabei im Prinzip mit Revisionen oder vereinfacht gesagt mit Kopien. Es gibt bei einem VCS einen zentralen Ort, an dem der Quellcode verwaltet und die jeweiligen neuen Versionen gespeichert werden. Das System ermöglicht dadurch das Verfolgen von Änderungen in Texten. Dabei ist es prinzipiell egal, ob es sich um Quellcode Ihrer iOS-App handelt oder eine Rezeptsammlung für Kuchen. Solange es sich um Text handelt, werden verschiedene Stände Ihrer Entwicklungsarbeit gespeichert und mit Metadaten angereichert. Dabei kann es sich um den Releasestand 1.0 Ihrer App handeln. Sie entwickeln Ihren Code weiter, können aber immer auf den Release stand 1.0 wechseln, um z.B. Fehler zu beheben. Natürlich kann so ein System auch Bilder oder andere Assets verwalten, aber die Veränderungen in einem Bild kann ein VCS nicht darstellen.

Doch nach all der Theorie stellt sich die Frage, wie mit so einem System für die iOS-Entwicklung gearbeitet werden kann? Genau das soll nun erläutert werden.

In dem Kontext der App-Entwicklung für iOS ist Apples Xcode für jeden Entwickler DAS gesetzte Entwicklungstool. Glücklicherweise ist hier bereits eine Integration für das Verwenden von VCS vorgesehen. Das erspart Ihnen den harten Einstieg mit der Kommandozeile. In diesem Rahmen soll das VCS Git kurz vorgestellt werden. Dieses Open Source Tool wurde bereits für das Entwickeln des Linux-Kernel genutzt und nicht zuletzt von Linus Torvalds selbst entwickelt. Bevor es losgeht, sei noch einmal ganz klar gesagt, dass auch Entwickler, die alleine programmieren, unbedingt ein VCS nutzen sollten. Schon im Einzelbetrieb sind die Vorteile nicht zu unterschätzen. Selbst wenn ein Projekt nur von einem Entwickler erstellt wird, hat dieser die Herausforderung zu meistern, seinen Quellcode über den gesamten Lebenszyklus seiner Entwicklung zu verwalten. Mehrere physische Kopien der Entwicklungsstände des Projekts auf einem Server würden es dabei sehr unübersichtlich machen. Sicher ist das Verwalten per Quellcode-Server noch eleganter. Dabei wird der Code nicht lokal, sondern auf einem entfernten Server verwaltet. Aber hier sollen der generelle Nutzen des VCS Git erläutert und die damit zugrundeliegenden Konzepte praktisch umgesetzt werden. Dabei wird auf die vorhandenen Funktionen bzw. die Integration in Xcode zurückgegriffen. Keine zusätzlichen Tools sind dafür involviert. Was kann das Standardtool von Apple leisten? Die verwendeten Screenshots sind aus Xcode 6.3.1. Das folgende Beispiel führt nun lebendig in den Umgang mit dem VCS Git und Xcode ein. Nach dieser Einführung sollten Sie über die Einbindung eines Git-Servers oder das Nutzen einer Plattform wie GitHub nachdenken, damit Sie auch mit Ihren Kollegen gemeinsam entwickeln können. Auch die Git-Kommandozeile könnte dann für Sie interessant werden. Aber solche Themen entführen Sie bereits tief in Git. Hier soll erst einmal mit den Mitteln von Git in Xcode begonnen werden.

Das erste Projekt mit Git begleiten

Es soll eine neue App für das iPhone entwickelt werden. Da Sie bereits viel über Git und den Nutzen eines VCS gehört haben, wollen Sie dieses Projekt mit der Unterstützung von Git erstellen. Wenn Sie unter Xcode ein Projekt anlegen, ist bereits dort schon die Möglichkeit der Git-Integration als VCS vorhanden. Beim letzten Schritt vor dem Erstellen des neuen Projektes wird im Auswahldialog zur Dateiablage die Möglichkeit geboten, Create git repository on… zu setzen.

bild_00

Bild 1: Git-Unterstützung schon bei der Projektanlage. Quelle: Xcode 6.3.1.

Normalerweise würde ein VCS immer einen entfernten Server nutzen, auf dem der Quellcode hinterlegt wird. Git bietet hier sogar das lokale Versionieren an und kommt daher schon ohne Serverkomponente aus. Erstellen Sie daher ein neues iOS-Projekt für iPhone mit Swift-Unterstützung und dem Single-View Application Template. Dabei darf das Häkchen für die Git-Unterstützung nicht vergessen werden. Ohne, dass Sie es gemerkt haben, wurde nun ein sogenanntes Repository angelegt. Git erstellt dafür ein Verzeichnis mit dem Namen .git. Durch den führenden Punkt ist es für das Mac-Dateisystem als versteckt gekennzeichnet. Im Finder ist es daher nicht auffindbar. Führen Sie allerdings das Kommando

defaults write com.apple.finder AppleShowAllFiles TRUE

aus, wird der Finder neu gestartet und das Verzeichnis ist jetzt sichtbar, wie im folgenden Bild angezeigt.

bild_02

Bild 2:             Ansicht der versteckten Dateien im Finder. Quelle: Xcode 6.3.1.

Nun kann mit der Versionierung gearbeitet werden. Die zu erstellende App ist sehr simpel, da diese ja nur der Demonstration dient. Als Erstes erweitern Sie dazu die Datei ViewController.swift mit einer neuen Funktion, die die Antwort auf die Frage des Lebens geben soll. Das Ergebnis ist dabei natürlich 42.

Listing 1: Beispielfunktion QuestionOfLife

func QuestionOfLife() -> Int {
var questionOfLife = 42;
return questionOfLife;
}

Bisher hat sich Ihre Arbeit mit Xcode nicht geändert. Nach dem Erweitern der Datei bemerken Sie aber nun den Buchstaben M neben der Datei.

Bild03

Bild 3: Projektansicht in Xcode Quelle: Xcode 6.3.1.

Damit teilt Xcode mit, dass sich etwas verändert hat, das noch nicht im VCS ist. Das Hinzufügen von Änderungen in einem VCS wird auch als Commit bezeichnet. Da Xcode eine Integration anbietet, kann dieser Vorgang ganz einfach durch den Menüpunkt Source Control -> Commit gesteuert werden. Das damit geöffnete Fenster zeigt die Änderungen zur letzten im VCS hinterlegten Revision an.

bild04

Bild 4: Differenzsansicht von zwei Versionen in Xcode. Quelle: Xcode 6.3.1.

Neben der Codeänderung wird im unteren Bereich auf eine Commit Message gewartet. Hier geben Sie eine Logmeldung ein, damit Sie die Änderung bzw. die neue Revision nachvollziehen können. In Projekten können hier auch z.B. Ticket-Nummern zu gemeldeten Bugs hinterlegt werden. Es ist einfach ein Freitext, der die Änderung beschreiben soll. Zum Abschluss senden Sie die Änderung durch Bestätigung des Button Commit 1 File an Git. Natürlich benötigt eine App mehr Code, aber für den Moment wollen wir annehmen, dass die Version 1.0 mit den Änderungen fertiggestellt ist. Jede Änderung in Git ist eine Revision, die mit einem Hash dargestellt wird. Im Source Control-Menü können Sie die Änderungen mit Hilfe des Menüpunktes History sehen.

Leider kann in Xcode nicht einfach auf eine Revision geklickt werden und es wird zu diesem Stand der Datei gesprungen. Zudem wäre es besser, wenn der Änderungsstand von allen Dateien mit einem sprechenden Namen verbunden werden könnte. Generell gibt es die Möglichkeit, einen Stand von Dateien mit einem sogenannten Tag zu versehen. In unserem Beispiel kann dies die Version 1.0 sein. Leider beherrscht Xcode das Tagging von Git nicht in der Oberfläche. Sie haben nun zwei Möglichkeiten: Entweder nutzen Sie Git mit der Kommandozeile und führen

git tag -a v1.0 -m 'tagging Version 1.0'
im Terminal aus. Alternativ nutzen Sie das populäre Feature von sogenannten Branches. Dies bringt außerdem noch weitere Vorteile mit sich.

Geteiltes Leid ist halbes Leid – die Branches

Das Nutzen von Branches ist sehr populär, denn diese Außenstellen (Branch) leben in Git für sich selbst. Das heißt, dass das Erzeugen eines Branches mit dem Namen „Release 1.0“ quasi eine komplette Kopie der Dateistände erstellt, die eigenständig weiterentwickelt werden kann. Damit können Bugfixes für das Release 1.0 erstellt und versioniert werden, obwohl an dem sogenannten Master-Branch die Entwicklung der eigentlichen App weitergeht. Auch das Zusammenführen von Branches ist möglich. Da Sie als Entwickler viel mit Xcode arbeiten und das Branch-Feature im Source-Control Menü unterstützt wird, erstellen Sie nun Ihren ersten Branch. Xcode fragt Sie dabei nach dem Namen des Branches, dieser soll in diesem Fall die Abkürzung rv1 für „release version 1“ tragen.

Wenn Sie mit dem Erstellen des ersten Branches fertig sind, meldet sich ein Kollege bei Ihnen, um zu fragen, wie es mit der App so läuft. Sie zeigen ihm sofort mit Stolz die neue Funktion für die Frage nach dem Leben. Er ist der Ansicht, dass die Funktion zwar gut sei, aber in eine eigene Datei gehöre. Diese Verbesserung implementieren Sie sofort.

Dafür wechseln Sie (switch Branch) im Source Control-Menü vom Branch rv1 in den Branch master. Jetzt wird noch eine neue Swift-Datei mit dem Namen MeineFunktionen.swift erstellt. Dabei taucht nach dem Erstellen der Datei neben dem Dateinamen ein A in Xcode auf, was daran liegt, dass das VCS diese Datei noch nicht kennt. Dabei ist ein entsprechender Commit auch hier einfach über das Source Control-Menü möglich. Neben der neuen Datei mit dem A ist auch noch ein M neben den Project-Settings zu sehen. Xcode verwaltet seine Projekte schließlich auch in eigenen Dateien, was sich durch das Hinzufügen einer neuen Datei zum Projekt auch geändert hat. Hier muss also ebenfalls ein entsprechender Commit durchgeführt werden. Damit haben Sie Ihre nächste Version erstellt. Vergessen Sie nicht, eine aussagekräftige Commit-Nachricht zu schreiben. Damit beherrschen Sie das Hinzufügen und Ändern Ihrer Dateien für Git in Xcode.

 

Was machen Sie, wenn „es“ passiert?

Zufrieden mit den bisherigen Erfolgen verschieben Sie die Funktion QuestionOfLife in die neue Datei und speichern diese, ohne sie zu committen! Ein Kollege holt Sie aufgeregt in ein Meeting, in dem Sie erfahren, dass die Entwicklung Ihrer App gestoppt wird, um so schnell wie möglich ein Release an Apple zu schicken. Ein Mitbewerber ist auf die gleiche App-Idee gekommen und nun ist Geschwindigkeit gefragt. Wieder am Arbeitsplatz, sehen Sie die Buchstaben M neben den Dateien ViewController.swift und MeineFunktionen.swift. Anstatt nun die Änderungen weiter zu entwickeln, müssen Sie an die Version vor der Änderung herankommen. Hier gibt es nun zwei Möglichkeiten: Wenn Ihre gesamten aktuellen Änderungen rückgängig gemacht werden sollen, reicht ein Klick auf den Punkt Discard all Changes… im Source Control-Menü aus. Alternativ kann auch ein Discard Changes pro Datei über das Kontextmenü durchgeführt werden. Damit wird die Datei in den Zustand des letzten Commit zurückversetzt. Leider ist in unserem Fall damit die Datei MeineFunktionen.swift leer, aber vorhanden. Eine andere Möglichkeit ist, das gesamte Projekt in den Zustand einer früheren Release-fähigen Version zu bringen. Glücklicherweise haben Sie einen Branch angelegt. In diesen können Sie nun einfach mittels switch wechseln. Nun erstellen Sie die App mit den Daten der Version 1 und senden diese zur Freigabe an Apple. So schnell konnten Sie reagieren, da Sie mit einem VCS gearbeitet haben. In diesen Beispielen wurde sogar nur die Standardfunktionalität von Xcode genutzt.

 

Die dunkle und die helle Seite – eine Zusammenfassung

Dies war nur ein sehr kleiner Ausschnitt der Möglichkeiten von Git. Doch was haben Sie dabei lernen können? Selbst ohne die Implementierung eines VCS-Servers ist das Verwenden von Git im Rahmen von Xcode sehr simpel. Die generellen Aufgaben wie das Commit sind sehr einfach und bieten komplette GUI-Unterstützung. Das Vergleichen von Code zwischen Versionen ist sehr gut gelöst. Leider ist das Wechseln in alte Revisionen nicht so einfach möglich, hier könnte Apple nachbessern. Positiv ist, dass das Erstellen von Branches sehr einfach ist. Auch muss generell keinerlei Kommandozeilenarbeit getätigt werden. Damit aber die vollen Features von Git genutzt werden können, bleibt das Nutzen der Kommandozeile nicht aus.