Veröffentlicht am 07-03-2019

Rewrite History mit Git Rebase Interactive und Reflog

Bildnachweis: https://www.pexels.com/photo/person-typing-on-typewriter-958164/

Bevor ich mit dem interaktiven Umbasieren meiner Commits begann, hatte ich beängstigende Dinge darüber gehört. Aber beim Codieren geht es darum, Geschichten zu erzählen und Umbasierung ist Teil der Reise. Es hilft Ihrem Code, eine klarere Geschichte zu erzählen und macht den Commit-Verlauf Ihres Repositorys lesbarer. Und dank reflog muss es nicht gefährlich sein.

Warum interaktiv rebasieren?

Mit Git können Sie Ihre Commits mit der interaktiven Basis neu anordnen. Sehen Sie sich zunächst Ihr Protokoll mit dem Befehl an:

Git Log

Dadurch wird die Liste der Commits in Ihrem Terminal geöffnet. Drücken Sie die Eingabetaste, um einen Bildlauf durchzuführen, und geben Sie dann q ein, um die Liste zu verlassen und zum Terminal zurückzukehren. Angenommen, Ihr Protokoll sieht folgendermaßen aus:

begehen ca82a6dff817ec66f44342007202690a93763949
Autor: Clementine Pirlot 
Datum: Mo Mar 17 21:52:11 2008 -0700

    Fix Tippfehler

Commit 605bd3bcb608e1e8451d4b2432f8ecbe6306e7e7
Autor: Clementine Pirlot 
Datum: Sa 15.03 16:40:33 2008 -0700

    Fügen Sie Komponententests hinzu
begehen 085bb3bcb608e1e8451d4b2432f8ecbe4324e7e7
Autor: Clementine Pirlot 
Datum: Sa 15.03 16:40:33 2008 -0700

    Tun Sie etwas, das nicht mehr zutrifft
Commit a11bef06a3f659402fe7563abf99ad00de2209e6
Autor: Clementine Pirlot 
Datum: Sa 15.03. 10:31:28 2008 -0700

    Funktionalität hinzufügen

Sie möchten nicht, dass der Tippfehler und der nicht mehr zutreffende Tipp in Ihrem Verlauf angezeigt werden. Sie bringen keinen Wert und fügen der Funktionalität unnötige Verpflichtungen hinzu. Sie können viele interaktive Rebases hintereinander ausführen, aber für dieses Beispiel möchten wir diese 4 Commits ändern. Der zu tippende Befehl lautet

Git Rebase -i KOPF ~ 4

Das -i ist für interaktive Funktionen und der HEAD ~, gefolgt von einer Zahl, gibt die Anzahl der letzten Commits an, die Sie in diese Rebase einschließen möchten a11bef06). Dieser Befehl öffnet den Standardtexteditor von git, der normalerweise vim ist. Wenn Sie kein Fan von vim sind, können Sie es mit git config --global core.editor "code --wait" ändern und den Code durch einen beliebigen Editor ersetzen. Sobald die Rebase-Datei geöffnet ist, werden für jede dieser Commits eine Zeile und einige hilfreiche Dokumentationen angezeigt.

Pick a11bef0 Funktionalität hinzufügen
pick 085bb3b Tun Sie etwas, das nicht mehr zutrifft
Wählen Sie 605bd3b Hinzufügen von Komponententests
Wählen Sie ca82a6d Fix Tippfehler
# Rebase eef025f..52d795e auf eef025f (4 Befehle)
# Befehle:
# p, wählen Sie  = use commit
# r, umformulieren  = Commit verwenden, aber die Commit-Nachricht bearbeiten
# e, edit  = use commit, aber zum Ändern aufhören
# s, squash  = Commit verwenden, aber in vorheriges Commit verschmelzen
# f, fixup  = wie "squash", aber verwerfen Sie die Protokollnachricht dieses Commits
# x, exec  = Ausführen des Befehls (der Rest der Zeile) mit Shell
# b, break = hier stoppen
# d, drop  = Commit entfernen
# l, label 
# t, reset 
# m, merge [-C  | -c ] 
#. Erstellen Sie ein Merge-Commit mit den ursprünglichen Merge-Commits
#. Nachricht (oder der Oneline, wenn keine ursprüngliche Zusammenführungsfestschreibung war
#. spezifizierten). Verwenden Sie -c , um die Commit-Nachricht neu zu formulieren.
#
# Diese Zeilen können nachbestellt werden. Sie werden von oben nach unten ausgeführt.
# Wenn Sie hier eine Zeile entfernen, WIRD DAS COMMIT VERLOREN.
# Wenn Sie jedoch alles entfernen, wird die Rebase abgebrochen.
# Beachten Sie, dass leere Commits auskommentiert werden

Kümmern wir uns zuerst um das nicht mehr relevante. Dies ist Code, der für diesen Zweig nicht mehr nützlich ist, etwas, das Sie ausprobiert haben, das sich dann herausstellte, als ob es nicht nötig war (zum Beispiel nach einem Refactor-Commit, der diese Änderungen aufgehoben hat). Wir möchten dieses Commit und seine Änderungen vollständig verwerfen und aus der Zweighistorie löschen. Dazu ersetzen Sie das Pick-Schlüsselwort entweder mit drop oder der Abkürzung d.

drop 085bb3b Tun Sie etwas, das nicht mehr zutrifft

Nun für das Tippfehler-Commit: Dies sind Änderungen, die wir im Code beibehalten möchten, aber wir möchten nicht, dass ein Commit nur für diesen Zweck vorliegt. Daher möchten wir die Codeänderungen in ein anderes Commit integrieren, in das wir den Tippfehler gemacht haben. In unserer Datei hier kommt das Tippfehler-Commit nicht direkt nach dem Commit, zu dem es gehört. Es gibt das Test-Commit und das Commit nicht mehr zwischendurch. Um sicherzustellen, dass unser Tippfehler in das erste Commit dieser Liste aufgenommen wird, verschieben wir die gesamte Zeile direkt darunter. Dies kann auch verwendet werden, um einfach die Reihenfolge der Commits zu ändern, ohne sie mit einem Schlüsselwort zu ändern. Es könnte die Lesbarkeit der Geschichte erleichtern, wenn sie einem logischen Fortschritt folgt.

Hier haben wir mehrere Optionen, um dieses Commit in die erste einzubeziehen. Wir können uns für ein Fixup entscheiden, das unsere Änderungen mit dem vorherigen Commit zusammenführt und unsere Commit-Nachricht verwirft, oder wir können es quetschen, wodurch ein Fixup und ein Re-Word durchgeführt werden, damit wir die Nachricht des vorherigen Commits neu schreiben können. Was wir hier tun werden, ist ein Fixup, da die Commit-Nachricht des ersten Commits nicht geändert werden muss. Also ersetzen wir pick durch unser neues Keyword, entweder fixup oder f.

Nach all diesen Änderungen sieht unsere Datei jetzt so aus:

Pick a11bef0 Funktionalität hinzufügen
Fixup ca82a6d Tippfehler behoben
drop 085bb3b Tun Sie etwas, das nicht mehr zutrifft
Wählen Sie 605bd3b Hinzufügen von Komponententests

Wenn Sie alle Änderungen vorgenommen haben, können Sie das Dokument speichern und geben Sie in Ihrem Terminal den Typ git rebase --continue ein. Möglicherweise haben Sie Konflikte, die gelöst werden müssen. Manchmal passiert es mir, wenn ich die Reihenfolge der Commits ändere. Beheben Sie in diesem Fall die Konflikte, speichern Sie die Datei, stellen Sie sie bereit, und geben Sie git rebase --continue erneut ein. Es sollte dann sagen:

Refraes / Heads / Master erfolgreich aktualisiert und aktualisiert.

Sie haben jetzt die saubere Geschichte, die Sie wollten!

Wenn Sie diese 4 Commits nicht gepusht haben, können Sie jetzt pushen, und wenn Sie sie bereits gepusht haben, müssen Sie pushen, da sich Ihr Verlauf geändert hat. Es ist sehr wichtig, dass Sie niemals einen Zweig erzwingen, den andere verwenden. Beispielsweise möchten Sie dies normalerweise tun, wenn Ihre PR akzeptiert wurde und Sie sie bereinigen möchten, bevor Sie sie zusammenführen.

Es gibt viele andere nützliche Befehle als "drop and fixup", wie Sie in der Dokumentation jeder interaktiven Rebase-Datei sehen können. Ich verwende häufig umformulieren und bearbeiten, die erste, um eine Festschreibungsnachricht zu ändern, und die zweite für feinere Änderungen, zum Beispiel, wenn ich eine Datei oder eine Änderung aus einem bestimmten Festschreiben entfernen muss.

Aber ist es nicht gefährlich?

Was passiert, wenn alles in die Hölle geht, habe ich all diese 4 Verpflichtungen verloren? Nein, git ist das fantastische Werkzeug, es ist dein Rücken. Erstens, wenn Sie Konflikte bekommen und erkennen, dass es zu kompliziert ist, um es wert zu sein, können Sie das Ganze mit git rebase --abort abbrechen, und Ihre 4 Verpflichtungen werden wieder in den ursprünglichen Zustand versetzt. Ich habe es mehrmals verwendet, als ich versuchte, die Reihenfolge meiner Commits zu ändern, aber es stellte sich als schwierig heraus, und nach meinem Abbruch würde ich die interaktive Rebase erneut mit meinen Änderungen am Fixup-Typ erneut ausführen.

Was wäre, wenn Sie neu basierten und erkannten, dass Sie einen Fehler gemacht haben, das Commit, das Sie ablegten, immerhin nützlich war und Sie eine Zeile benötigten? Dann kommt Reflog ins Spiel. Sie können immer noch in den Zustand zurückkehren, wenn Sie Ihre 4 Commits hatten, selbst nachdem Sie gedrückt haben. Reflog ist ähnlich wie git log, aber mit einem Unterschied: Betrachten Sie es wie Aktionen. Jede Aktion, die Sie in git ausführen, wird dort gespeichert. Sie könnten sehen, wie sich Ihre Branche verändert, Ihre Züge gezogen und dankenswerterweise auch Ihre Rebellen! Um zu der Zeit vor der Rebase zurückzukehren, müssen Sie diese Aktion in Ihrem Reflog finden. Geben Sie git reflog in Ihr Terminal ein und suchen Sie nach der Zeile, bevor Sie mit dem Rebase beginnen:

52a395e (HEAD -> master, origin / master, origin / HEAD) HEAD @ {3}: rebase -i (start): checkout HEAD ~ 4
56d785e (HEAD -> master, origin / master, origin / HEAD) HEAD @ {4}: pull: checkout 52d795ea1809abc941a9d267c1e8b024b9cae89e

Hier haben wir es bei HEAD @ {4}. Jetzt können Sie git reset --hard HEAD @ {4} eingeben und Sie werden zu diesem Zeitpunkt zurückkehren (seien Sie vorsichtig, da Sie alle Änderungen, die nicht festgeschrieben wurden, für immer verlieren werden). Sie können gewaltsam pushen, da Sie Ihre Historie noch einmal neu geschrieben haben, oder Sie können sich vor dem Pushen erneut anders abmessen.

Dank reflog muss interaktives Umbasieren nicht unheimlich und gefährlich sein. Sie können der Chef Ihrer eigenen Geschichte sein und saubere Zweige mit Ihrem Repository zusammenführen. Wir codieren nicht für Computer, es ist ihnen egal, ob es sich um C # oder binär handelt, wir codieren für Menschen. Genauso wie das Schreiben von Code mit verständlichen Namen und Fortschritt für Sie und andere Personen, die Ihren Code lesen, wichtig ist, ist der logische Fortschritt in Ihrer Historie einfach zu lesen und zu verwalten. Sie können Ihre Geschichte so erzählen, wie sie erzählt werden soll, ohne Lärm oder Ablenkungen, und Ihre Rezensenten und alle, die sich den Verlauf dieser App ansehen, werden von Anfang bis Ende reibungslos behandelt.

Siehe auch

Hacking für die CommunityVielleicht lernst du nicht CodeTech Career Guide: So erhalten Sie Ihren ersten technischen JobErleichterung des Teamlernens mit der Mob-Programmierung