git switch und git restore statt git checkout

Mich fragen ja häufiger mal Leute, was sich so in den letzten Git-Versionen getan hat. Das frage ich mich natürlich auch immer mal wieder und lese jedes Mal die Release-Notes und finde in der Regel nichts spannendes was mich als Endnutzer interessiert. Ja, Verbesserungen der Performance und Fehlerkorrekturen sind gut und wichtig – als „normaler“ Nutzer merkt man davon allerdings recht wenig.

Interessant ist allerdings die Neuerung in Git Version 2.23, die Mitte August veröffentlicht wurde. Es gibt nun zwei experimentelle neue Kommandos: git switch und git restore. Beide koexistieren zu dem bisherigen Kommando git checkout was den gängigen Git Nutzer bekannt sein sollte. Wie zuvor erwähnt, handelt es sich um „experimentelle“ Kommandos, das heißt, die Funktion wird zwar bleiben, die Parameter können sich allerdings noch weiter verändern und sind möglicherweise noch fehlerbehaftet.

In diesem Blogpost begutachte ich die beiden neuen Befehle und zeige die Unterschiede zu dem bisherigen Kommando auf.

Status Quo

Bevor wir uns die neuen Befehle anschauen lohnt es sich noch einmal aufzufrischen, wie der Status Quo ist und warum die neuen Befehle praktisch und sinnvoll sind.

Der Subbefehl checkout wird vielfältig in Git eingesetzt. Der wohl gängigste Einsatz ist der Wechsel von einem auf den anderen Branch:

$ git checkout master

Dieser Befehl wechselt vom aktuellen Branch auf den Branch master. Es ist auch möglich einen neuen Branch zu erstellen und direkt darauf zu wechseln:

$ git checkout -b feature/1337

Dieser Befehl nimmt den aktuellen Branch, auf dem man sich gerade befindet, und legt den Branch namens feature/1337 an und wechselt direkt da hin. Möchte man einen anderen Branch als Basis nehmen, tippt man den Namen dahinter als weiteren Parameter ein. Alternativ lässt sich mit git branch feature/1337 ebenfalls ein Branch anlegen, auf dem man nicht automatisch hin wechselt.

Checkout als Befehl zum Wechseln und Erzeugen von Branches sollte für die meisten geübten Git-Nutzern bekannt und gängig sein. Genau so lege ich immer meine Branches auf der Kommandozeile bisher an.

Der andere Modus von Checkout ist das Auschecken von Dateien aus anderen Branches, Revisionen bzw. dem Verwerfen von Änderungen aus dem Staging-Bereich und der Arbeitskopie. Dies wird durch die Nutzung von doppelten Minuszeichen -- ermöglicht.

In der bereits versionierten Datei index.html sind Änderungen vorhanden, die nicht im Staging-Bereich enthalten sind. Um die Änderungen zu verwerfen, kann folgender Befehl verwendet werden:

$ git checkout -- index.html

Somit sind die Änderungen in der Arbeitskopie verworfen und können nicht wiederhergestellt werden. Der Inhalt der Datei index.html wurde auf den Stand von HEAD – also dem aktuell ausgecheckten Commit – zurückgesetzt. Der Befehl kann auch verwendet werden, um einzelne Dateien aus einem anderen Branch auszuchecken und im aktuellen Projekt abzulegen.

Dieser Befehl würde dann wie folgt lauten:

$ git checkout feature/1337 -- index.html

Die Datei index.html aus dem Branch feature/1337 wird dann von Git im aktuellen Projektverzeichnis abgelegt. Mit einem git status wird dann auch aufgelistet, dass sich die Datei verändert hat. Dies natürlich nur unter der Voraussetzung, dass sich die Datei in beiden Branches unterscheiden. Statt eines Branches können auch andere Revisionen angegeben werden. Denn nicht vergessen: ein Branch sind letztendlich auch nur Zeiger auf einen bestimmten Commit, der stetig aktualisiert wird.

Status Futurus

Mit den neuen Kommandos switch und restore wird alles besser! Na gut, zumindest wird deutlich einfacher zu verstehen, was diese tun. Mit beiden Befehlen werden alte Zöpfe nach und nach abgeschnitten und die Befehle klarer und besser zu nutzen.

Git-Nutzer wissen vermutlich, dass viele Befehle nicht so offensichtlich sind und es nicht unbedingt auf Anhieb nachvollziehbar ist, was welcher Befehl tut. Das gute Beispiel ist eben git checkout womit man sowohl Branches wechseln kann, als auch Dateien aus anderen Revisionen holen kann.

git switch

Für das Wechseln von Branches gibt es jetzt den Befehl git switch. Mit diesem lassen sich ebenfalls neue Branches anlegen. Das Wechseln von einem Branch funktioniert wie äquivalent:

$ git switch feature/1337

Für das Erstellen eines neuen Branches existiert der Parameter -c:

$ git switch -c feature/1337

Dies ist äquivalent zu git checkout -b feature/1337. Interessant ist auch der Parameter -C, der mit einem großem C geschrieben wird. Dies ist effektiv ein forciertes Anlegen eines neuen Branches, da der Zielbranch hart überschrieben wird. Hier gilt es also aufzupassen.

git restore

Der zweite Befehl ist git restore. Wie der Name schon verrät, lassen sich Dateien wiederherstellen.

Die erste Nutzungsmöglichkeit ist bereits, wenn man eine neue Datei anlegt und diese zum Staging-Bereich hinzufügt.

$ echo "Hallo" > hallo.txt
$ git add hallo.txt
$ git status
Auf Branch master
Zum Commit vorgemerkte Änderungen:
  (benutzen Sie "git restore --staged <Datei>..." zum Entfernen aus der Staging-Area)
        neue Datei:     hallo.txt

Git zeigt schon ab der neuen Version 2.23 an, dass man git restore verwenden soll und kann. In diesem Fall lässt sich mit dem Befehl die Datei aus dem Staging-Bereich wieder herausnehmen. Restore lässt sich natürlich auch dafür verwenden eine Datei aus einem anderen Commit zu holen. Als zusätzlicher Parameter wird --source benötigt:

$ git restore --source feature/1337 index.html

Dies holt die Datei in das Arbeitsverzeichnis rein. Mit dem zusätzlichen Parameter --staged wird die Änderung hingegen direkt in den Staging-Bereich geschoben.

Sowohl git restore als auch git switch besitzen ein paar mehr Parameter. Meiner Meinung nach sind beide sinnvolle Ergänzungen und machen die Nutzung von Git deutlich angenehmer. Schwierig ist für den geübten Git-Nutzer nur sich die neuen Befehle einzuprägen. Bei mir sind die bisherigen Befehle schon länger in Fleisch und Blut übergangen, sodass ich jetzt erstmal umlernen muss.