Git Reset und Reflog

GitBeginner
Jetzt üben

Einführung

Willkommen, Git-Zeitreisender! Heute werden wir zwei mächtige Git-Funktionen erkunden, die Ihnen eine beispiellose Kontrolle über die Historie Ihres Repositorys geben: git reset und git reflog. Diese Werkzeuge sind wie die erweiterten Bedienelemente Ihrer Git-Zeitmaschine. Sie ermöglichen es Ihnen, zwischen verschiedenen Zuständen Ihres Projekts zu springen und sogar „verlorene“ Arbeit wiederzufinden.

Der Befehl git reset ist ein vielseitiges Werkzeug, mit dem Sie Änderungen rückgängig machen, Dateien aus dem Staging-Bereich entfernen und sogar Ihre Commit-Historie umschreiben können. Doch mit großer Macht kommt auch große Verantwortung, und git reset kann für Neulinge anfangs etwas einschüchternd wirken. Hier kommt git reflog ins Spiel – es fungiert als Sicherheitsnetz, das alle Änderungen an den Referenzen Ihres Repositorys (wie die Spitzen von Branches) protokolliert. So können Sie selbst nach den drastischsten Resets alles wiederherstellen.

In diesem Lab behandeln wir:

  1. Soft Reset: Den HEAD verschieben, ohne das Arbeitsverzeichnis oder den Staging-Bereich zu verändern.
  2. Mixed Reset: Änderungen aus dem Staging-Bereich entfernen, während die Modifikationen im Arbeitsverzeichnis erhalten bleiben.
  3. Hard Reset: Änderungen vollständig verwerfen.
  4. Reflog nutzen: Wiederherstellung nach „destruktiven“ Operationen.
  5. Zeitbasierte Resets: Das Repository in einen Zustand zu einem bestimmten Zeitpunkt zurückversetzen.

Am Ende dieses Labs werden Sie ein solides Verständnis dafür haben, wie Sie diese leistungsstarken Git-Funktionen sicher und effektiv einsetzen. Sie werden in der Lage sein, die Historie Ihres Repositorys souverän zu manipulieren, immer mit dem Wissen, dass Sie im Notfall den Weg zurück finden.

Lassen Sie uns eintauchen und die Meisterschaft über git reset und reflog erlangen!

Einrichten Ihres Arbeitsbereichs

Bevor wir mit dem Resetten und Refloggen beginnen, richten wir einen Arbeitsbereich mit einigen Commits ein, an denen wir experimentieren können. Wir erstellen ein neues Verzeichnis, initialisieren ein Git-Repository und fügen einige Dateien mit mehreren Commits hinzu.

Öffnen Sie Ihr Terminal und geben Sie diese Befehle ein:

cd ~/project
mkdir git-reset-lab
cd git-reset-lab
git init

Nun erstellen wir einige Dateien und führen eine Reihe von Commits durch. Kopieren Sie dazu die folgenden Befehle in Ihr Terminal:

echo "## Git Reset and Reflog Lab" > README.md
git add README.md
git commit -m "Initial commit"

echo "function add(a, b) { return a + b; }" > math.js
git add math.js
git commit -m "Add addition function"

echo "function subtract(a, b) { return a - b; }" >> math.js
git add math.js
git commit -m "Add subtraction function"

echo "function multiply(a, b) { return a * b; }" >> math.js
git add math.js
git commit -m "Add multiplication function"

Lassen Sie uns kurz zusammenfassen, was wir gerade getan haben:

  1. Wir haben eine README-Datei erstellt und unseren ersten Commit gemacht.
  2. Wir haben eine JavaScript-Datei mit einer Additionsfunktion erstellt und committet.
  3. Wir haben eine Subtraktionsfunktion zur gleichen Datei hinzugefügt und committet.
  4. Schließlich haben wir eine Multiplikationsfunktion hinzugefügt und committet.

Jetzt haben wir ein Repository mit einer Historie, an der wir experimentieren können!

Soft Reset: Den HEAD verschieben

Die erste Art von Reset, die wir untersuchen, ist der „Soft“ Reset. Ein Soft Reset verschiebt den HEAD (und den aktuellen Branch) zu einem anderen Commit, ändert jedoch weder den Staging-Bereich noch das Arbeitsverzeichnis. Dies ist nützlich, wenn Sie einige Commits „rückgängig machen“ möchten, aber alle Änderungen für einen neuen, zusammengefassten Commit behalten wollen.

Probieren wir einen Soft Reset aus:

git reset --soft HEAD~2

Dieser Befehl setzt den HEAD um zwei Commits zurück (auf den Commit vor „Add subtraction function“). Das Kürzel ~2 bedeutet „zwei Commits vor dem aktuellen HEAD“. Sie können ~N verwenden, um N Commits zurückzugehen.

Wenn Sie nun git status ausführen, sehen Sie, dass die Änderungen aus den Commits „Add subtraction function“ und „Add multiplication function“ zusammen im Staging-Bereich liegen. Die Dateien in Ihrem Arbeitsverzeichnis haben sich nicht verändert. Die gesamte Arbeit aus diesen beiden Commits ist nun bereit, als ein einziger, neuer Commit gespeichert zu werden.

Dies ist besonders nützlich in Szenarien, in denen Sie Ihre letzten Commits zu einem einzigen „squashen“ (zusammenfassen) möchten. Sie führen einen Soft Reset um einige Commits zurück aus und erstellen dann einen neuen Commit mit all diesen Änderungen.

Lassen Sie uns diese Änderungen mit einer neuen Nachricht erneut committen:

git commit -m "Add subtraction and multiplication functions"

Denken Sie daran: Ein Soft Reset ist zwar im Allgemeinen sicher (da keine Änderungen verworfen werden), aber er schreibt die Historie um. Wenn Sie die ursprünglichen Commits bereits auf einen Server hochgeladen (gepusht) haben, müssten Sie einen Force-Push durchführen, um den Remote-Branch zu aktualisieren. Dies kann zu Problemen bei der Zusammenarbeit führen. Kommunizieren Sie daher immer mit Ihrem Team, bevor Sie eine geteilte Historie umschreiben!

Mixed Reset: Änderungen aus dem Staging entfernen

Die nächste Art von Reset ist der „Mixed“ Reset. Dies ist der Standardmodus für git reset, wenn Sie kein Flag angeben. Ein Mixed Reset verschiebt den HEAD und aktualisiert den Staging-Bereich entsprechend, rührt aber das Arbeitsverzeichnis nicht an.

Lassen Sie uns einige Änderungen vornehmen und sie in den Staging-Bereich aufnehmen:

echo "function divide(a, b) { return a / b; }" >> math.js
git add math.js

Angenommen, wir haben es uns anders überlegt und möchten diese Änderung doch noch nicht im Staging-Bereich haben. Wir können einen Mixed Reset verwenden:

git reset HEAD

Dies entfernt unsere Änderungen aus dem Staging-Bereich, behält sie aber im Arbeitsverzeichnis. Wenn Sie jetzt git status ausführen, sehen Sie, dass math.js modifiziert, aber nicht für den Commit vorgemerkt ist.

Der Mixed Reset ist hilfreich, wenn Sie Änderungen gestaged haben, dann aber entscheiden, dass Sie noch nicht bereit für den Commit sind. Vielleicht möchten Sie die Änderungen noch einmal überprüfen oder weitere Modifikationen vornehmen, bevor Sie sie erneut hinzufügen.

Beachten Sie, dass der Mixed Reset im Gegensatz zum Soft Reset den Staging-Bereich verändert. Er ist jedoch immer noch sicher in dem Sinne, dass keine Ihrer Arbeiten verworfen wird – alles befindet sich weiterhin in Ihrem Arbeitsverzeichnis.

Hard Reset: Änderungen verwerfen

Die dritte und drastischste Art des Resets ist der „Hard“ Reset. Ein Hard Reset verschiebt den HEAD, aktualisiert den Staging-Bereich UND aktualisiert das Arbeitsverzeichnis. Das bedeutet, dass alle Änderungen seit dem Commit, auf den Sie zurücksetzen, unwiderruflich verworfen werden.

Probieren wir einen Hard Reset aus:

git add math.js
git commit -m "Add division function"
git status
git reset --hard HEAD~1

Dies fügt unsere Divisionsfunktion hinzu und committet sie. Danach führen wir einen Hard Reset auf den vorherigen Commit aus, was unseren letzten Commit effektiv „rückgängig macht“ und die Änderungen löscht.

Wenn Sie sich math.js jetzt ansehen, werden Sie feststellen, dass die Divisionsfunktion verschwunden ist. Es ist so, als hätten wir sie nie geschrieben.

Ein Hard Reset ist mächtig, aber gefährlich. Er ist nützlich, wenn Sie eine Arbeit komplett verwerfen und von einem früheren Stand neu beginnen möchten. Seien Sie jedoch extrem vorsichtig damit, da er Änderungen dauerhaft löschen kann.

Überprüfen Sie immer doppelt, ob Sie auf den richtigen Commit zurücksetzen, bevor Sie einen Hard Reset durchführen. Wenn Sie unsicher sind, ist es sicherer, einen Soft oder Mixed Reset zu verwenden oder vor dem Experimentieren einen neuen Branch zu erstellen.

Reflog zur Wiederherstellung verlorener Commits nutzen

Was aber, wenn Sie feststellen, dass Sie die Divisionsfunktion gar nicht löschen wollten? Hier rettet uns git reflog. Das Reflog ist ein Protokoll aller Positionen, an denen sich der HEAD in Ihrem lokalen Repository befunden hat. Es ist wie eine Super-Historie, die sogar Befehle aufzeichnet, die die Historie umschreiben, wie eben Reset.

Schauen wir uns das Reflog an:

git reflog

Sie sollten eine Liste aller kürzlich durchgeführten Aktionen sehen, einschließlich Ihrer Resets. Jeder Eintrag hat einen Identifikator im Format HEAD@{n}.

Um Ihren verlorenen Commit wiederherzustellen, können Sie auf den Zustand vor Ihrem Hard Reset zurücksetzen:

git reset --hard HEAD@{1}

Dies setzt auf den Zustand des HEAD vor Ihrer letzten Aktion (welche der Hard Reset war) zurück.

Prüfen Sie math.js jetzt, und Sie sollten sehen, dass Ihre Divisionsfunktion wieder da ist!

cat math.js
function add(a, b) { return a + b; }
function subtract(a, b) { return a - b; }
function multiply(a, b) { return a * b; }
function divide(a, b) { return a / b; }

Das Reflog ist ein mächtiges Sicherheitsnetz, das es Ihnen ermöglicht, fast jeden Git-Unfall rückgängig zu machen. Denken Sie jedoch daran, dass es lokal auf Ihrem Rechner gespeichert wird und temporär ist (Einträge werden normalerweise 30 bis 90 Tage aufbewahrt). Es ist kein Ersatz für regelmäßige Backups oder das Pushen Ihrer Arbeit in ein Remote-Repository.

Zeitbasierte Resets

Git erlaubt es Ihnen auch, Ihr Repository auf einen Zustand zu einem ganz bestimmten Zeitpunkt zurückzusetzen. Dies kann nützlich sein, wenn Sie sich ungefähr erinnern, wann Ihr Repository in dem Zustand war, zu dem Sie zurückkehren möchten.

Probieren wir einen zeitbasierten Reset aus:

git reset --hard master@{"1 hour ago"}

Dies setzt Ihr Repository auf den Zustand von vor einer Stunde zurück. Sie können verschiedene Zeitangaben verwenden wie „yesterday“, „2 days ago“, „3 minutes ago“ usw.

Seien Sie vorsichtig mit zeitbasierten Resets, da sie weniger präzise sein können als das Zurücksetzen auf einen spezifischen Commit. Überprüfen Sie nach einem zeitbasierten Reset immer den Zustand Ihres Repositorys, um sicherzustellen, dass Sie dort gelandet sind, wo Sie hin wollten.

Denken Sie daran, dass Sie jederzeit das Reflog nutzen können, um einen zeitbasierten Reset rückgängig zu machen, falls er nicht das erwartete Ergebnis geliefert hat.

Zusammenfassung

Herzlichen Glückwunsch, Git-Zeitherrscher! Sie haben soeben einige der mächtigsten und potenziell gefährlichsten Befehle von Git gemeistert. Lassen Sie uns die wichtigsten Konzepte noch einmal zusammenfassen:

  1. Soft Reset: Verschiebt den HEAD, ohne den Staging-Bereich oder das Arbeitsverzeichnis zu ändern. Nützlich zum Zusammenfassen (Squashing) von Commits.
  2. Mixed Reset: Verschiebt den HEAD und aktualisiert den Staging-Bereich, lässt aber das Arbeitsverzeichnis unberührt. Ideal, um Änderungen aus dem Staging zu entfernen.
  3. Hard Reset: Verschiebt den HEAD und aktualisiert sowohl den Staging-Bereich als auch das Arbeitsverzeichnis. Mächtig, aber potenziell destruktiv.
  4. Reflog: Ein Sicherheitsnetz, das alle Änderungen am HEAD aufzeichnet und es Ihnen ermöglicht, fast jeden Git-Fehler zu korrigieren.
  5. Zeitbasierte Resets: Ermöglichen es Ihnen, Ihr Repository auf einen Zustand zu einem bestimmten Zeitpunkt in der Vergangenheit zurückzusetzen.

Denken Sie daran: Mit großer Macht kommt große Verantwortung. Während diese Befehle Ihnen eine unglaubliche Kontrolle über die Historie Ihres Repositorys geben, können sie bei unvorsichtiger Anwendung auch gefährlich sein. Prüfen Sie alles doppelt, bevor Sie einen Reset durchführen – insbesondere einen Hard Reset – und denken Sie daran, dass das Reflog Ihr bester Freund ist, wenn etwas schiefgeht.

Üben Sie diese Befehle auf Ihrem weiteren Git-Weg in einer sicheren Umgebung, bis Sie sich damit sicher fühlen. Es sind Werkzeuge, die Ihren Git-Workflow bei korrektem Einsatz massiv verbessern können.

Viel Erfolg beim Resetten, und möge Ihre Git-Historie stets sauber und aussagekräftig bleiben!