Wie können Sie das letzte Git-Add rückgängig machen?


193

Ist es möglich, die letzte inszenierte (nicht festgeschriebene) Änderung in git aufzuheben ? Angenommen, der aktuelle Zweig enthält viele Dateien, einige sind inszeniert, andere nicht. Irgendwann hat ein dummer Programmierer versehentlich Folgendes ausgeführt:

git add -- .

...anstatt:

git checkout -- .

Kann dieser Programmierer jetzt seine letzten Änderungen mit einem magischen Git- Befehl aufheben ? Oder hätte er sich verpflichten sollen, bevor er überhaupt experimentierte?


Heh. Wir haben jedoch eine nützliche Frage und Antwort daraus.
Steveha


Ich glaube, es ist nicht das Duplikat. OP in der anderen Frage fragt nach einer Möglichkeit, dies rückgängig zu machen oder diese Dateien aus dem Commit zu entfernen. Ich möchte (ed) genau und nur die Änderungen rückgängig machen, die mit dem letzten git addBefehl hinzugefügt wurden , insbesondere für die Dateien, in denen bereits Änderungen vorgenommen wurden und in denen einige Änderungen rückgängig gemacht und nicht bereitgestellt wurden. Ich kann nicht sagen, dass die andere Frage nicht verwandt ist.
Septagramm

1
Vielleicht hätte er sich verpflichten sollen, bevor er überhaupt experimentiert hat.
android.weasel

@ android.weasel ja, das war vor vielen Jahren ...
Septagram

Antworten:


299

Sie können verwenden git reset. Dadurch werden alle Dateien, die Sie nach Ihrem letzten Commit hinzugefügt haben, "aufgehoben".

Wenn Sie nur einige Dateien entfernen möchten, verwenden Sie git reset -- <file 1> <file 2> <file n>.

Es ist auch möglich, einige der Änderungen in Dateien mithilfe von zu entfernen git reset -p.


3
Wie traurig. Ich denke, es stimmt doch etwas nicht mit meinen Praktiken. Akzeptiere diese Antwort, weil du den -pWechsel erwähnt hast . Vielen Dank! :)
Septagramm

Erzeugt (für mich) den Fehler: fatal: Fehler beim Auflösen von 'HEAD' als gültige Referenz. Ich habe noch nichts festgeschrieben (neues Repo), nur git add. und bereute es. Ich möchte nicht das gesamte Add zurücksetzen, nur ein Verzeichnis. git reset - dir /*.* erzeugt den obigen Fehler.
Francis Davey

... Ah, ich sehe, was für mich passiert. Ich hatte noch nichts, auf das HEAD hinweisen konnte, und so schlug das Zurücksetzen des Git fehl (weil es auf dem HEAD funktioniert).
Francis Davey

42

Sie können das letzte Git-Add nicht rückgängig machen , aber Sie können alle adds seit dem letzten Commit rückgängig machen . git resetohne ein Commit-Argument wird der Index zurückgesetzt (nicht bereitgestellte Änderungen):

git reset

2
"Sie können das neueste Git-Add nicht rückgängig machen ": Wow, das ist überraschend und möglicherweise schmerzhaft. Gibt es dafür eine endgültige Quelle? Gibt es auch einen guten Grund, warum es so sein sollte? Vielen Dank!
Andrew Moylan

@ AndrewMoylan: Nun, es gibt keine automatische Möglichkeit, dies zu tun. Sie können immer reseteine einzelne Datei verwenden oder reset -pein bestimmtes Stück entfernen.
Knittl

15

Also die wahre Antwort auf

Kann dieser Programmierer jetzt seine letzten Änderungen mit einem magischen Git-Befehl aufheben?

ist eigentlich: Nein, man kann nicht nur den letzten inszenieren git add.

Das heißt, wenn wir die Frage wie folgt interpretieren:

Anfangsdatei:

void foo() {

}

main() {
    foo();
}

Erste Änderung gefolgt von git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Zweite Änderung gefolgt von git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

In diesem Fall git reset -philft das nicht, da die kleinste Granularität Linien sind. gitweiß das nicht über den Zwischenzustand von:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

nicht mehr.


Ich habe mich gefreut, weil dies als neuer Git-Benutzer eine wirklich wichtige Unterscheidung ist, die hervorhebt, was meine Freunde als "gute Check-in-Hygiene" beschreiben ... meine persönliche Erfahrung - es wurde als "Fahrgemeinschaft" (schlecht!) Beschrieben.
Benc


3

Zum jetzigen Zeitpunkt fordert git auf:

  1. use "git rm --cached <file>..." to unstagewenn Dateien nicht im Repo waren. Es löst die Dateien auf und hält sie dort.
  2. use "git reset HEAD <file>..." to unstageWenn sich die Dateien im Repo befanden und Sie sie als geändert hinzufügen. Die Dateien bleiben unverändert und werden nicht mehr bereitgestellt.

Meines Wissens können Sie das nicht rückgängig machen, git add --aber Sie können eine Liste von Dateien wie oben erwähnt entfernen.


2
  • Entfernen Sie die Datei aus dem Index, behalten Sie sie jedoch versioniert bei und lassen Sie nicht festgeschriebene Änderungen in der Arbeitskopie übrig:

    git reset head <file>
    
  • Setzen Sie die Datei von HEAD auf den letzten Status zurück, machen Sie Änderungen rückgängig und entfernen Sie sie aus dem Index:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>

    Dies ist erforderlich, da git reset --hard HEADes nicht mit einzelnen Dateien funktioniert.

  • <file>Aus dem Index und der Versionierung entfernen und die nicht versionierte Datei mit Änderungen in der Arbeitskopie beibehalten:

    git rm --cached <file>
    
  • <file>Aus der Arbeitskopie entfernen und vollständig versionieren:

    git rm <file>
    

2

Wenn Sie alle hinzugefügten Dateien zum Festschreiben aus git entfernen möchten

git reset

Wenn Sie eine einzelne Datei entfernen möchten

git rm <file>

1

Sie können verwenden

git reset

um die kürzlich hinzugefügten lokalen Dateien rückgängig zu machen

 git reset file_name

um die Änderungen für eine bestimmte Datei rückgängig zu machen


0

Je nach Größe und Umfang der Schwierigkeit können Sie einen (temporären) Scratch-Zweig erstellen und die aktuelle Arbeit dort festschreiben.

Wechseln Sie dann zu Ihrem ursprünglichen Zweig, checken Sie ihn aus und wählen Sie die entsprechenden Dateien aus dem Scratch-Commit aus.

Zumindest hätten Sie eine permanente Aufzeichnung des aktuellen und vorherigen Status, von dem aus Sie arbeiten können (bis Sie diesen Arbeitszweig löschen).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.