Serie: Versionskontrolle for the rest of us
- Teil 1: Das Prinzip hinter Subversion a.k.a. SVN
- Teil 2: SVN-Prinzipien an Beispielen erklärt
- Teil 3: Git für SVN-Umsteiger
- Teil 4: Das Prinzip Git an Beispielen erklärt
- Teil 5: Git für so halb-Fortgeschrittene
- Teil 5: Git und Branches
Ihr habt brav die bisherigen Teile dieser Serie durchstöbert? Cool, dann seid ihr ja bereits mit den Grundlagen von Git vertraut. Darauf können wir aufbauen.
Stashing
Nicht selten arbeitet man an einem Feature, hat schon ein paar Zeilen Code geschrieben und bekommt plötzlich ein Ticket rein, das auf einen Bug in der laufenden Anwendung aufmerksam macht. Bugs haben Priotität, darum macht ihr euch schnell ran, den Bug zu fixen.
Doch eure Alarmglocken schlagen Alarm. Wir können doch nicht die bisherigen Änderungen für das neue Feature zusammen mit dem Bugfix comitten. Richtig. Also können tun wir das schon, nur ist das nicht besonders praktikabel. Unabhängig davon, dass ihr unfertige Features im Master hättet: Commits sollten immer eine sinnvolle Einheit bilden. So lässt sich die History besser nachverfolgen und ggf. rückgängig machen. Und darum geht’s ja in der Versionskontrolle.
Was machen wir also? Stashen. So bezeichnet man in Git den Vorgang aktuelle Änderungen zwischenzuspeichern, um sie anschließend ohne schlechtes Gewissen zu verwerfen – temporär versteht sich. Ein plötzlich notwendiger Bugfix ist das Paradebeispiel für den Einsatzzweck dieser Funktion.
Die Implementierung ist recht easy:
git stash
Die Änderungen werden in einem Kellerspeicher abgelegt, first-in-last-out. Hat man den Bug gefixed und will die Änderungen wiederhaben, benutzt man
git stash pop
So einfach ist das.
Hilfe, ich habe beim Commit etwas vergessen
Passiert mir allzu oft: ich committe 2, 3 Änderungen und beim nächsten Blick auf den Code fällt mir ein „Ach nee, da müssen noch 2 Kommentare raus.“ Kommt vor den Kollegen immer doof, für sowas einen extra Commit zu bemühen. Darum kann man einen Commit rückgängig machen:
git reset --soft HEAD^1
Der Parameter --soft
sorgt dafür, dass die mit dem Commit gemachten Änderungen nicht verloren gehen, sondern direkt wieder gestaged werden. Git geht richtigerweise davon aus, dass wir die Änderungen nur ergänzen wollen. Das Konstrukt HEAD^1
gibt an, wie weit wir zurück wollen. Da wir nur den letzten Commit wollen, sagen wir „Ich will die Head-Revision minus 1 Commit.“
Also einfach die 2 Kommentare entfernen, Änderungen stagen, git commit
und der Commit ist korrigiert.
Wichtig ist hierbei, dass ihr nur Commits ändert, die bisher lediglich lokal gemacht worden, also noch nicht zu GitHub o.ä. gesendet (gepusht) wurden.
Push und Pull
Wer bei der Vorstellung der Prinzipien hinter Git aufgepasst hat, weiß, dass Pull ein Update aus dem Repository holt und Push ein solches sendet (vgl.: Update/Commit bei SVN). Vor jedem Push ein Pull, bitte daran denken! Git wird euch zur Not drauf hinweisen 😉
Wenn ihr zum Testen ein (kostenloses) Repository bei GitHub anlegen möchtet, folgt einfach der Empfehlung vom letzten Mal und durchlauft TryGit. Ich hatte zwar angekündigt darauf einzugehen, jedoch könnte ich es nie besser machen als die CodeSchool-Mädels und -Jungs. Darum: hin da!
Nichtsdestotrotz noch etwas zu der Push- und Pullerei.
Pull
Ein Pull erfolgt so hier:
git pull origin master
git pull
is der eigentlich Befehl, die beiden Wörter dahinter geben an, was genau gepullt werden soll. origin
ist die Bezeichnung für das remote Repository. Der Name an sich ist willkürlich, ist aber ein Quasi-Standard. Es macht also Sinn diesen beizubehalten. master
ist der Branch in diesem Remote Repository. Den Master als Branch zu bezeichnen, ist zwar unüblich, aber genau so ist es in Git. Auch der Master ist ein Branch.
Was wollen wir also machen: die Inhalte aus dem master
Branch des Remote Repositories holen und mit dem lokalen Zustand abgleichen. Falls es Neuerungen gibt, die wir lokal noch nicht haben, werden diese entsprechend eingepflegt. Git erzeugt dabei u.U. automatisch einen Merge Commit, der den lokalen Fortschritt mit dem remote Fortschritt vereint.
Das wiederum lässt sich durch anhängen des Parameters –rebase
umgehen. Dazu aber im nächsten Teil mehr, da die Sachlage hier etwas komplexer ist. Merken wir uns einfach, dass git pull —rebase
gemütlicher ist. Und der faule Entwickler liebt gemütlich.
Push
Push ist also das Senden an das Remote Repository. Die Syntax dafür ist
git push origin master
Viel mehr gibt es dazu auch nicht zu sagen. Was es mit origin master
auf sich hat, dürftet ihr schon wissen. Aber… eigentlich ist doch das ständige Angeben des Remote Branches überflüssig. Schließlich wollen wir Änderungen aus dem Branch holen, der dem Lokalen entsprichen, an dem wir gerade arbeiten. Selbiges gilt für das Pushen.
Gute Nachricht: insofern ihr eine aktuelle Version (=>1.8) von Git verwendet (kriegt ihr mit git —version
heraus), könnt ihr beim Pullen den Remote Branch weglassen. Um das gleiche für git push
zu erreichen, müsst ihr folgenden Befehl abfeuern:
git config --global push.default "current"
Das setzt voraus, dass eure lokalen Branches genauso heißen, wie die remote Branches (also der lokale master
ist remote origin master
, ein lokaler Branch namens cooles_feature
heißt remote origin cooles_feature
). Mehr Informationen dazu gibt’s hier.
Push und Pull nur bei cleanem Status
Die Push- und Pull-Kommandos werden nur ausgeführt, wenn euer Working Directory clean ist, d.h. ihr keine nicht comitteten Änderungen habt (doppelte Verneinungen FTW!!!). Falls dem so ist, wird Git die Ausführung verweigern. Abhilfe schafft an dieser Stelle git stash
(siehe Anfang des Artikels).
Etwas mehr Farbe bitte
Wer im Terminal etwas Farbe haben möchte, wird für folgendes Kommando dankbar sein:
git config --global --add color.ui true
Das war’s… noch nicht ganz
Ein wichtiger Punkt fehlt noch: das Thema Branches. Da Branches eine Angelegenheit für sich sind und die Auseinandersetzung damit erst nach einiger Gewöhnung an die Git-Basics Sinn macht, werde ich noch einen Teil hinterherschieben.
Bis dahin dürft ihr die hier vermittelten Kenntnisse verinnerlichen und euch fragen: wird diese Serie zur Versionkontrolle je ein Ende finden? 😉