Ich freue mich darauf, ein Commit aufzuteilen und nicht sicher, welche Reset-Option verwendet werden soll.
Ich habe mir die Seite angesehen Können Sie mir erklären, was "git reset" auf Englisch bedeutet? , aber mir wurde klar, dass ich nicht wirklich verstehe, was der Git-Index oder der Staging-Bereich ist, und daher haben die Erklärungen nicht geholfen.
Auch die Anwendungsfälle für --mixed
und --soft
sehen in dieser Antwort für mich gleich aus (wenn Sie das Problem beheben und erneut festlegen möchten.) Kann jemand es noch mehr zusammenbrechen? Ich weiß, dass --mixed
wahrscheinlich die Option ist, aber ich möchte wissen, warum. Was ist schließlich mit --hard
?
Kann mir jemand ein Workflow-Beispiel geben, wie die Auswahl der 3 Optionen erfolgen würde?
Wenn Sie eine Datei in Ihrem Repository ändern, wird die Änderung zunächst nicht in Szene gesetzt. Um es festzuschreiben, müssen Sie es mit git add
bereitstellen, dh dem Index hinzufügen. Wenn Sie ein Commit durchführen, werden die Änderungen festgeschrieben, die dem Index hinzugefügt wurden.
git reset
ändert sich mindestens, wohin der aktuelle Zweig (HEAD
) zeigt. Der Unterschied zwischen --mixed
und --soft
besteht darin, ob auch Ihr Index geändert wird. Wenn wir also mit dieser Reihe von Commits auf Zweig master
sind:
- A - B - C (master)
HEAD
points to C
und der Index stimmt mit C
überein.
Wenn wir git reset --soft B
ausführen, zeigt master
(und damit HEAD
) jetzt auf B
, der Index enthält jedoch weiterhin die Änderungen von C
; git status
zeigt sie als inszeniert an. Wenn wir also an dieser Stelle git commit
ausführen, erhalten wir ein neues Commit mit den gleichen Änderungen wie C
.
Okay, also schon wieder von hier:
- A - B - C (master)
Nun machen wir git reset --mixed B
. (Hinweis: --mixed
ist die Standardoption). Wieder zeigen master
und HEAD
auf B, aber diesmal wird der Index auch so geändert, dass er mit B
übereinstimmt. Wenn wir an dieser Stelle git commit
ausführen, passiert nichts, da der Index HEAD
übereinstimmt. Wir haben immer noch die Änderungen im Arbeitsverzeichnis, aber da sie nicht im Index enthalten sind, zeigt git status
sie als nicht bereitgestellt an. Um sie zu übergeben, würden Sie git add
und dann wie üblich festlegen.
Und schließlich ist --hard
dasselbe wie --mixed
(es ändert Ihre HEAD
und den Index), außer dass --hard
auch Ihr Arbeitsverzeichnis ändert. Wenn wir uns in C
befinden und git reset --hard B
ausführen, werden die in C
hinzugefügten Änderungen sowie alle nicht festgeschriebenen Änderungen, die Sie vorgenommen haben, entfernt und die Dateien in Ihrer Arbeitskopie passen mit B
zusammen. Da Sie auf diese Weise dauerhaft Änderungen verlieren können, sollten Sie git status
immer ausführen, bevor Sie einen Hard-Reset durchführen, um sicherzustellen, dass Ihr Arbeitsverzeichnis sauber ist oder dass Sie Ihre nicht festgeschriebenen Änderungen nicht mehr benötigen.
Und zum Schluss noch eine Visualisierung:
Bitte beachten Sie, dies ist eine vereinfachte Erklärung, die als erster Schritt zum Verständnis dieser komplexen Funktionalität dienen soll.
Kann für visuelle Lernende hilfreich sein, die visualisieren möchten, wie ihr Projektstatus nach jedem dieser Befehle aussieht:
Für diejenigen, die Terminal mit aktivierter Farbe verwenden (Git config --global color.ui auto):
git reset --soft A
und du siehst die Sachen von B und C in grün (inszeniert und bereit zum Commit)
git reset --mixed A
(oder git reset A
) und Sie sehen das Zeug von B und C in Rot (unstaging und bereit, inszeniert zu werden (grün) und dann festgeschrieben).
git reset --hard A
und Sie werden die Änderungen von B und C nirgendwo mehr sehen (wird so aussehen, als ob sie nie existieren würden)
Oder für diejenigen, die ein GUI-Programm wie 'Tower' oder 'SourceTree' verwenden
git reset --soft A
und Sie sehen B & Cs Sachen im Bereich 'Staged Files', die bereit sind zu übergeben
git reset --mixed A
(oder git reset A
), und Sie werden B & Cs Sachen im Bereich "nicht bereitgestellte Dateien" sehen, die bereit sind, inszeniert zu werden und dann festgeschrieben werden
git reset --hard A
und Sie werden die Änderungen von B und C nirgendwo mehr sehen (wird so aussehen, als ob sie nie existieren würden)
Im einfachsten Sinne:
--soft
: uncommit ändert sich, Änderungen werden in den Hintergrund gestellt (index).--mixed
(Standardeinstellung): uncommit + unstage changes, Änderungen werden in working tree belassen.--hard
: uncommit + unstage + delete ändert sich, nichts übrig.Hier ist eine grundlegende Erklärung für TortoiseGit-Benutzer:
git reset --soft
und --mixed
lassen Ihre Dateien unberührt.
git reset --hard
tatsächlich ändern Sie Ihre Dateien entsprechend dem Commit, auf den Sie zurücksetzen.
In TortoiseGit wird das Konzept von the index von der GUI sehr verborgen. Wenn Sie eine Datei ändern, müssen Sie git add
nicht ausführen, um die Änderung zum Bereitstellungsbereich/Index hinzuzufügen. Wenn Sie einfach Änderungen an vorhandenen Dateien vornehmen, die den Dateinamen nicht ändern, sind git reset --soft
und --mixed
gleich! Sie werden nur einen Unterschied bemerken, wenn Sie neue Dateien hinzugefügt oder Dateien umbenannt haben. Wenn Sie git reset --mixed ausführen, müssen Sie in diesem Fall Ihre Datei (en) erneut aus der Liste Nicht versionierte Dateien hinzufügen.
Alle anderen Antworten sind großartig, aber ich finde es am besten, sie zu verstehen, indem ich die Dateien in drei Kategorien aufteile: unstaged
, staged
, commit
:
--hard
sollte leicht zu verstehen sein, es stellt alles wieder her--mixed
(Standard) : unstaged
Dateien: nicht ändernstaged
Dateien: Verschieben nach unstaged
commit
Dateien: Verschieben nach unstaged
--soft
: unstaged
Dateien: nicht ändernstaged
files: nicht änderncommit
Dateien: Verschieben nach staged
In Summe:
--soft
verschiebt alles (außer unstaged
Dateien) in staging area
--mixed
Option verschiebt alles in unstaged area
Der grundlegende Unterschied zwischen den verschiedenen Optionen des Befehls git reset ist wie folgt.
Hier gibt es eine Reihe von Antworten mit einer falschen Vorstellung von git reset --soft
. Während es eine bestimmte Bedingung gibt, unter der git reset --soft
nur HEAD
(ausgehend von einem Status eines abgelösten Kopfes) in der Regel (und für die beabsichtigte Verwendung) ändert, verschiebt es die Zweigreferenz, die Sie gerade ausgecheckt haben. Natürlich ist dies nicht möglich, wenn Sie keinen Zweig ausgecheckt haben (daher ändert sich die Bedingung, bei der git reset --soft
nur HEAD
ändert).
Ich habe festgestellt, dass dies der beste Weg ist, über git reset
nachzudenken. Sie bewegen nicht nur HEAD
( alles macht das ), Sie bewegen auch den branch ref, z. B. master
. Dies ist ähnlich wie beim Ausführen von git commit
(der aktuelle Zweig wird zusammen mit HEAD
verschoben), außer dass Sie ein new-Commit erstellen (und zu diesem wechseln), Sie zu einem previous verpflichten.
Dies ist der Punkt von reset
, der einen Zweig in etwas anderes als ein neues Commit ändert und HEAD
nicht ändert. Das sehen Sie im Dokumentationsbeispiel:
Machen Sie ein Commit rückgängig und machen Sie es zu einem Zweigzweig
$ git branch topic/wip (1) $ git reset --hard HEAD~3 (2) $ git checkout topic/wip (3)
- Sie haben ein paar Commits gemacht, erkennen jedoch, dass sie zu früh im "Master" -Zweig waren. Sie möchten sie weiterhin in einem Zweigzweig polieren. Erstellen Sie also einen Zweig "Zweig/Zweig" aus dem aktuellen HEAD.
- Spulen Sie den Master-Zweig zurück, um diese drei Commits zu entfernen.
- Wechseln Sie in den Zweig "Topic/Wip" und arbeiten Sie weiter.
Was ist der Sinn dieser Befehlsfolge? Sie möchten einen Zweig verschieben, hier master
. Wenn Sie also master
ausgecheckt haben, führen Sie git reset
aus.
Die am besten gewählte Antwort hier ist im Allgemeinen gut, aber ich dachte, ich würde dies hinzufügen, um die verschiedenen Antworten mit falschen Vorstellungen zu korrigieren.
git reset --soft <ref>
: Setzt den Verzweigungszeiger für die aktuell ausgecheckte Verzweigung auf das Festschreiben an der angegebenen Referenz zurück. Dateien in Ihrem Arbeitsverzeichnis und Index werden nicht geändert. Wenn Sie in dieser Phase einen Commit ausführen, gelangen Sie direkt dorthin, wo Sie vor dem git reset
-Befehl waren.
git reset --mixed <ref>
oder gleichwertig
git reset <ref>
:
Tut was --soft
tut UND setzt auch den Index auf das Commit an der angegebenen Referenz zurück. Während git reset --soft HEAD
nichts tut (weil es heißt, den ausgecheckten Zweig in den ausgecheckten Zweig zu verschieben), ist git reset --mixed HEAD
oder gleichwertig git reset HEAD
ein allgemeiner und nützlicher Befehl, da er den Index auf den Status Ihres letzten Commits zurücksetzt.
git reset --hard <ref>
: macht, was --mixed
tut UND überschreibt auch Ihr Arbeitsverzeichnis. Dieser Befehl ähnelt git checkout <ref>
, mit der Ausnahme, dass (und dies ist der entscheidende Punkt bei reset
) alle Formen von git reset
bewegen den Verzweigungsreferenz HEAD
zeigt auf.
Es ist nicht sinnvoll zu sagen, dass ein Befehl die HEAD
verschiebt. Jeder Befehl, der sich an der Stelle Ihres Commit-Verlaufs ändert, verschiebt die HEAD
. Das ist was HEAD
ist, ein Zeiger auf wo immer Sie sind. HEAD
is bist du und bewegt sich also immer, wenn du es tust.
--soft
: Weist Git an, HEAD auf ein anderes Commit zurückzusetzen, sodass Index und das Arbeitsverzeichnis in keiner Weise geändert werden. Alle Dateien, die zwischen dem ursprünglichen HEAD und dem Commit geändert wurden, werden bereitgestellt.
--mixed
: Genau wie bei soft wird dies HEAD auf ein anderes Commit zurückgesetzt. Der Index wird ebenfalls zurückgesetzt, damit er dem Index entspricht, während das Arbeitsverzeichnis nicht berührt wird. Alle Änderungen verbleiben im Arbeitsverzeichnis und erscheinen als geändert, jedoch nicht als stufenweise.
--hard
: Dadurch wird alles zurückgesetzt - es setzt HEAD auf ein anderes Commit zurück, setzt den Index entsprechend zurück und setzt auch das Arbeitsverzeichnis zurück.
Der Hauptunterschied zwischen --mixed
und --soft
ist, ob auch Ihr Index geändert wird oder nicht. Mehr dazu hier .
Eine kurze Antwort, in welchem Kontext die 3 Optionen verwendet werden:
Um behält die aktuellen Änderungen im Code, aber um den Commit-Verlauf neu zu schreiben:
soft
: Sie können alles auf einmal festschreiben und ein neues Commit mit einer neuen Beschreibung erstellen (wenn Sie torotise git oder die meisten anderen GUIs verwenden, ist dies diejenige, die verwendet werden soll, da Sie immer noch auswählen können, welche Dateien Sie beim Commit und beim Erstellen möchten Mehrere Commits auf diese Weise mit unterschiedlichen Dateien. In Sourcetree würden alle Dateien für das Commit bereitgestellt.)mixed
: Sie müssen die einzelnen Dateien erneut zum Index hinzufügen, bevor Sie ein Commit ausführen (in Sourcetree würden alle geänderten Dateien nicht in Szene gesetzt).Um Ihre Änderungen zu verlieren auch im Code:
hard
: Sie schreiben nicht nur den Verlauf neu, sondern verlieren alle Ihre Änderungen bis zu dem Punkt, an dem Sie sie zurücksetzenSie müssen sich nicht zwingen, sich an die Unterschiede zwischen ihnen zu erinnern. Denken Sie darüber nach, wie Sie sich tatsächlich festgelegt haben.
1. Nehmen Sie einige Änderungen vor.
2.git add.
3.gc -m "Ich habe etwas getan"
Mit Soft, Mixed und Hard können Sie Ihre Vorgänge von 3 auf 1 aufgeben.
Weich "vorgetäuscht", nie gesehen zu haben, dass Sie "gc -m" gemacht haben.
Gemischtes "vorgetäuscht", nie zu sehen, dass Sie "git add" gemacht haben.
Hart "vorgetäuscht", nie zu sehen, dass Sie Dateiänderungen vorgenommen haben.
Bevor auf diese drei Optionen eingegangen wird, muss man drei Dinge verstehen.
1) Geschichte/KOPF
2) Stufe/Index
3) Arbeitsverzeichnis
reset --soft: Verlauf geändert, HEAD geändert, Arbeitsverzeichnis wird nicht geändert.
reset --mixed: Verlauf geändert, HEAD geändert, Arbeitsverzeichnis mit nicht bereitgestellten Daten geändert.
reset --hard: Verlauf geändert, HEAD geändert, Arbeitsverzeichnis wird mit verlorenen Daten geändert.
Es ist immer sicher mit Git --soft zu gehen. Bei komplexer Anforderung sollte eine andere Option verwendet werden.
mkaraseks Antwort ist großartig, in einfachen Worten können wir sagen ...
git reset --soft
: Setzen Sie die HEAD
auf das beabsichtigte Commit, behalten Sie jedoch Ihre Änderungen gegenüber dem letzten Commit beigit reset --mixed
: ist dasselbe wie git reset --soft
, der einzige Unterschied besteht jedoch darin, dass Sie Ihre Änderungen gegenüber den letzten Commits nicht änderngit reset --hard
: Setzen Sie Ihre HEAD
in dem von Ihnen angegebenen Commit und setzen Sie alle Ihre Änderungen vom letzten Commit zurück, einschließlich nicht festgeschriebener Änderungen.