wake-up-neo.net

Was ist der Unterschied zwischen git reset --mixed, --soft und --hard?

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?

576
Michael Chinen

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)

HEADpoints 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: enter image description here

1187
mkarasek

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)

63
timhc22

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.
41
Mo Ali

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. 

21
James Lawruk

In diesen Fällen mag ich ein Bild, das dies hoffentlich erklären kann:

git reset --[hard/mixed/soft]:

 enter image description here

So wirken sich verschiedene Bereiche aus

  1. Hard => WorkingDir + Index + HEAD
  2. Gemischt => Index + KOPF
  3. Soft => HEAD nur (Index und Arbeitsverzeichnis unverändert).
7
Tomer Ben David

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) :
    1. unstaged Dateien: nicht ändern
    2. staged Dateien: Verschieben nach unstaged
    3. commit Dateien: Verschieben nach unstaged
  • --soft:
    1. unstaged Dateien: nicht ändern
    2. staged files: nicht ändern
    3. commit Dateien: Verschieben nach staged

In Summe:

  • Die Option --soft verschiebt alles (außer unstaged Dateien) in staging area
  • --mixed Option verschiebt alles in unstaged area
5
Hansen W

Der grundlegende Unterschied zwischen den verschiedenen Optionen des Befehls git reset ist wie folgt.

  • --soft: Setzt nur HEAD auf den von Ihnen ausgewählten Commit zurück. Funktioniert im Wesentlichen wie git Checkout, erstellt jedoch keinen separaten Kopfstatus.
  • --mixed (Standardoption): Setzt den HEAD auf den Commit zurück, den Sie im Verlauf ausgewählt haben, und macht die Änderungen im Index rückgängig.
  • --hard: Setzt den HEAD auf den Commit zurück, den Sie in der Historie ausgewählt haben, macht die Änderungen im Index rückgängig und macht die Änderungen in Ihrem Arbeitsverzeichnis rückgängig.
1

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)
  1. 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.
  2. Spulen Sie den Master-Zweig zurück, um diese drei Commits zu entfernen.
  3. 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.

Ändern Sie Ihren Zweig

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.

Ändern Sie auch Ihren Index

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.

Ändern Sie auch Ihr Arbeitsverzeichnis

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.

Ein Hinweis zu "diesem und jenem Befehl bewegt den KOPF":

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 HEADist, ein Zeiger auf wo immer Sie sind. HEADis bist du und bewegt sich also immer, wenn du es tust. 

1
De Novo

--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 .

1
Nesha Zoric

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ücksetzen
1
Nickpick

Sie 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. 

1
qinmu2127

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.

1
Suresh Sharma

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 bei
  • git reset --mixed: ist dasselbe wie git reset --soft, der einzige Unterschied besteht jedoch darin, dass Sie Ihre Änderungen gegenüber den letzten Commits nicht ändern
  • git 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. 
0
Vivek Maru