Im Allgemeinen besteht git resetdie Funktion darin, den aktuellen Zweig zu nehmen und ihn auf einen anderen Punkt zurückzusetzen und möglicherweise den Index und den Arbeitsbaum mitzubringen. Genauer gesagt, wenn Ihre Hauptniederlassung (derzeit ausgecheckt) so ist:
- A - B - C (HEAD, master)
und Sie erkennen, dass der Meister auf B und nicht auf C zeigen soll. Sie werden ihn verwenden git reset B, um ihn dorthin zu verschieben:
- A - B (HEAD, master) # - C is still here, but there's no branch pointing to it anymore
Exkurs: Dies unterscheidet sich von einer Kasse. Wenn du rennen würdest git checkout B, würdest du folgendes bekommen:
- A - B (HEAD) - C (master)
Sie sind in einem getrennten HEAD-Zustand gelandet. HEAD, Arbeitsbaum, Index alle übereinstimmen B, aber der Hauptzweig wurde bei zurückgelassen C. Wenn Sie Dzu diesem Zeitpunkt ein neues Commit durchführen , erhalten Sie dieses, was wahrscheinlich nicht das ist, was Sie wollen:
- A - B - C (master)
\
D (HEAD)
Denken Sie daran, dass beim Zurücksetzen keine Festschreibungen vorgenommen werden. Es wird lediglich ein Zweig (der ein Zeiger auf eine Festschreibung ist) aktualisiert, um auf eine andere Festschreibung zu verweisen. Der Rest ist nur ein Detail dessen, was mit Ihrem Index und Arbeitsbaum passiert.
Anwendungsfälle
Ich beschreibe viele der Hauptanwendungsfälle git resetin meinen Beschreibungen der verschiedenen Optionen im nächsten Abschnitt. Es kann wirklich für eine Vielzahl von Dingen verwendet werden; Der gemeinsame Thread besteht darin, dass bei allen der Zweig, der Index und / oder der Arbeitsbaum zurückgesetzt werden, um auf ein bestimmtes Commit zu verweisen oder mit diesem übereinzustimmen.
Dinge, auf die man achten muss
--hardkann dazu führen, dass Sie wirklich Arbeit verlieren. Es ändert Ihren Arbeitsbaum.
git reset [options] commitkann dazu führen, dass Sie Commits (irgendwie) verlieren. Im obigen Spielzeugbeispiel haben wir das Commit verloren C. Es befindet sich immer noch im Repo, und Sie können es finden, indem Sie auf git reflog show HEADoder schauen git reflog show master, aber es ist von keiner Filiale aus mehr zugänglich.
Git löscht solche Commits nach 30 Tagen dauerhaft, aber bis dahin können Sie C wiederherstellen, indem Sie erneut auf einen Zweig zeigen ( git checkout C; git branch <new branch name>).
Argumente
Um die Manpage zu paraphrasieren, wird am häufigsten das Formular verwendet git reset [<commit>] [paths...], mit dem die angegebenen Pfade aus dem angegebenen Commit auf ihren Status zurückgesetzt werden. Wenn die Pfade nicht bereitgestellt werden, wird der gesamte Baum zurückgesetzt, und wenn das Commit nicht bereitgestellt wird, wird es als HEAD (das aktuelle Commit) angesehen. Dies ist ein allgemeines Muster für Git-Befehle (z. B. Auschecken, Diff, Protokollieren, obwohl die genaue Semantik variiert), daher sollte es nicht allzu überraschend sein.
Zum Beispiel git reset other-branch path/to/fooalles setzt in path / to / foo in seinen Zustand in anderem Zweig, git reset -- .setzt das aktuelle Verzeichnis auf seinen Zustand in HEAD, und ein einfaches git resetsetzt alles auf seinen Zustand in dem Kopf.
Der Hauptarbeitsbaum und die Indexoptionen
Es gibt vier Hauptoptionen, um zu steuern, was während des Zurücksetzens mit Ihrem Arbeitsbaum und Index passiert.
Denken Sie daran, dass der Index der "Staging-Bereich" von git ist - hier gehen die Dinge, wenn Sie git addin Vorbereitung auf das Festschreiben sagen .
--hardpasst alles zu dem Commit, auf das Sie zurückgesetzt haben. Dies ist wahrscheinlich am einfachsten zu verstehen. Alle Ihre lokalen Änderungen werden blockiert. Eine Hauptanwendung besteht darin, Ihre Arbeit wegzublasen, aber keine Commits zu wechseln: git reset --hardbedeutet git reset --hard HEAD, dass Sie den Zweig nicht ändern, sondern alle lokalen Änderungen entfernen . Das andere ist einfach, einen Zweig von einem Ort zum anderen zu verschieben und den Index / Arbeitsbaum synchron zu halten. Dies ist derjenige, der Sie wirklich dazu bringen kann, Arbeit zu verlieren, weil er Ihren Arbeitsbaum ändert. Seien Sie sehr, sehr sicher, dass Sie lokale Arbeit wegwerfen möchten, bevor Sie welche ausführen reset --hard.
--mixedist die Standardeinstellung, dh git resetbedeutet git reset --mixed. Es setzt den Index zurück, aber nicht den Arbeitsbaum. Dies bedeutet, dass alle Ihre Dateien intakt sind, aber alle Unterschiede zwischen dem ursprünglichen Commit und dem, auf das Sie zurückgesetzt wurden, als lokale Änderungen (oder nicht verfolgte Dateien) mit Git-Status angezeigt werden. Verwenden Sie diese Option, wenn Sie feststellen, dass Sie einige schlechte Commits durchgeführt haben, aber die gesamte geleistete Arbeit beibehalten möchten, damit Sie sie beheben und erneut festlegen können. Zum Festschreiben müssen Sie dem Index erneut Dateien hinzufügen ( git add ...).
--softBerührt den Index oder den Arbeitsbaum nicht. Alle Ihre Dateien sind wie bei intakt --mixed, aber alle Änderungen werden wie changes to be committedbeim Git-Status angezeigt (dh zur Vorbereitung auf das Festschreiben eingecheckt). Verwenden Sie diese Option, wenn Sie feststellen, dass Sie einige schlechte Verpflichtungen eingegangen sind, die Arbeit jedoch gut ist. Sie müssen sie lediglich anders festlegen. Der Index bleibt unberührt, sodass Sie sofort ein Commit durchführen können, wenn Sie möchten. Das resultierende Commit hat denselben Inhalt wie vor dem Zurücksetzen.
--mergewurde kürzlich hinzugefügt und soll Ihnen helfen, eine fehlgeschlagene Zusammenführung abzubrechen. Dies ist erforderlich, da Sie git mergetatsächlich eine Zusammenführung mit einem Dirty-Work-Baum (einer mit lokalen Änderungen) versuchen können, solange sich diese Änderungen in Dateien befinden, die von der Zusammenführung nicht betroffen sind. git reset --mergeSetzt den Index zurück (wie --mixed- alle Änderungen werden als lokale Änderungen angezeigt) und setzt die von der Zusammenführung betroffenen Dateien zurück, lässt die anderen jedoch in Ruhe. Dies wird hoffentlich alles wieder so machen, wie es vor der schlechten Zusammenführung war. Normalerweise verwenden Sie es als git reset --merge(Bedeutung git reset --merge HEAD), da Sie nur die Zusammenführung zurücksetzen und den Zweig nicht verschieben möchten. ( HEADwurde noch nicht aktualisiert, da die Zusammenführung fehlgeschlagen ist)
Nehmen wir an, Sie haben die Dateien A und B geändert und versuchen, in einem Zweig zusammenzuführen, der die Dateien C und D geändert hat. Die Zusammenführung schlägt aus irgendeinem Grund fehl und Sie entscheiden, sie abzubrechen. Sie verwenden git reset --merge. Es bringt C und D zurück zu dem, in dem sie sich befanden HEAD, lässt jedoch Ihre Änderungen an A und B in Ruhe, da sie nicht Teil der versuchten Zusammenführung waren.
Möchten Sie mehr wissen?
Ich denke, das man git resetist wirklich ziemlich gut dafür - vielleicht brauchst du ein bisschen Verständnis dafür, wie Git funktioniert, damit sie wirklich eintauchen. Insbesondere wenn Sie sich die Zeit nehmen, sie sorgfältig zu lesen, sind diese Tabellen, in denen der Status der Dateien im Index und im Arbeitsbaum für alle verschiedenen Optionen und Fälle aufgeführt ist, sehr, sehr hilfreich. (Aber ja, sie sind sehr dicht - sie vermitteln eine Menge der oben genannten Informationen in einer sehr präzisen Form.)
Seltsame Notation
Die "seltsame Notation" ( HEAD^und HEAD~1), die Sie erwähnen, ist lediglich eine Abkürzung für die Angabe von Commits, ohne einen Hash-Namen wie verwenden zu müssen 3ebe3f6. Es ist vollständig dokumentiert im Abschnitt "Festlegen von Revisionen" der Manpage für git-rev-parse mit vielen Beispielen und zugehöriger Syntax. Das Caret und die Tilde bedeuten eigentlich verschiedene Dinge :
HEAD~ist die Abkürzung für HEAD~1und bedeutet das erste übergeordnete Element des Commits. HEAD~2bedeutet das erste Elternteil des Commits. Stellen Sie sich HEAD~n"n Commits vor HEAD" oder "den Vorfahren der n-ten Generation von HEAD" vor.
HEAD^(oder HEAD^1) bedeutet auch das erste übergeordnete Element des Commits. HEAD^2bedeutet das zweite übergeordnete Element des Commits . Denken Sie daran, dass ein normales Zusammenführungs-Commit zwei übergeordnete Elemente hat - das erste übergeordnete Element ist das zusammengeführte Commit und das zweite übergeordnete Element ist das festgeschriebene Commit. Im Allgemeinen können Zusammenführungen tatsächlich beliebig viele Eltern haben (Octopus-Zusammenführungen).
- Die
^und ~Betreiber können aneinandergereiht werden, wie in HEAD~3^2den zweit Eltern des dritten Generation Vorfahren HEAD, HEAD^^2die zweite Mutter des ersten Elternteil HEADoder sogar HEAD^^^, was gleichwertig ist HEAD~3.
