11450 Stimmen

Wie kann ich "git add" vor der Übertragung rückgängig machen?

Ich habe versehentlich Dateien mit dem Befehl zu Git hinzugefügt:

git add myfile.txt

Ich habe noch nicht ausgeführt git commit . Gibt es eine Möglichkeit, dies rückgängig zu machen, so dass diese Dateien nicht in die Übertragung aufgenommen werden?

57 Stimmen

Beginnend mit Git v1.8.4 werden alle folgenden Antworten, die HEAD o head können nun @ anstelle von HEAD stattdessen. Siehe diese Antwort (letzter Abschnitt) um zu erfahren, warum Sie das tun können.

5 Stimmen

Ich habe eine kleine Übersicht erstellt, die alle Möglichkeiten zum Aufheben einer Datei zeigt: stackoverflow.com/questions/6919121/

8 Stimmen

Wenn Sie Eclipse verwenden, ist es so einfach wie das Entfernen der Markierung der Dateien im Dialogfeld "Übertragen".

13654voto

genehack Punkte 126986

Sie können rückgängig machen git add vor der Übergabe mit

git reset <file>

was ihn aus dem aktuellen Index (der Liste "about to be committed") entfernt, ohne etwas anderes zu ändern.

Sie können verwenden

git reset

ohne einen Dateinamen, um alle fälligen Änderungen rückgängig zu machen. Dies kann nützlich sein, wenn zu viele Dateien vorhanden sind, um sie in angemessener Zeit einzeln aufzulisten.

In alten Versionen von Git sind die oben genannten Befehle äquivalent zu git reset HEAD <file> y git reset HEAD und schlägt fehl, wenn HEAD ist undefiniert (weil Sie noch keine Übertragungen in Ihrem Repository vorgenommen haben) oder mehrdeutig (weil Sie einen Zweig namens HEAD was eine Dummheit ist, die man nicht tun sollte). Diese wurde in Git 1.8.2 geändert In modernen Versionen von Git können Sie die oben genannten Befehle sogar vor dem ersten Commit verwenden:

"git reset" (ohne Optionen oder Parameter) führte früher zu einem Fehler, wenn Sie keine Commits in Ihrer History haben, aber jetzt gibt es Ihnen einen leeren Index (der zu einem nicht existierenden Commit passt, an dem Sie nicht einmal beteiligt sind).

Dokumentation: Git-Reset

162 Stimmen

Natürlich ist dies kein echtes Rückgängigmachen, denn wenn die falsche git add eine frühere unbestätigte Staged-Version überschrieben hat, können wir sie nicht wiederherstellen. Ich habe versucht, dies in meiner Antwort unten zu klären.

12 Stimmen

git reset HEAD *.ext donde ext sind die Dateien mit der angegebenen Erweiterung, die Sie entfernen möchten. Bei mir war es *.bmp & *.zip

1 Stimmen

Git reset sagte, dass die Änderungen rückgängig gemacht wurden, aber als ich einen weiteren git status ausführte, wurden sie immer noch als geändert angezeigt

2486voto

Rhubarb Punkte 33134

Sie wollen:

git rm --cached <added_file_to_undo>

Begründungen:

Als ich neu in diesem Bereich war, habe ich zuerst versucht

git reset .

(um meine gesamte ursprüngliche Eingabe rückgängig zu machen), nur um diese (nicht so) hilfreiche Nachricht zu erhalten:

fatal: Failed to resolve 'HEAD' as a valid ref.

Es stellt sich heraus, dass dies daran liegt, dass der HEAD ref (branch?) erst nach der ersten Übergabe existiert. Das heißt, Sie stoßen auf das gleiche Anfängerproblem wie ich, wenn Ihr Arbeitsablauf, wie meiner, etwas wie war:

  1. cd in mein großartiges neues Projektverzeichnis, um Git auszuprobieren, den neuen Renner

  2. git init

  3. git add .

  4. git status

    ... eine Menge Mist rollt vorbei ...

    \=> Verdammt, das wollte ich gar nicht alles hinzufügen.

  5. google "git add rückgängig machen"

    \=> Stack Overflow finden - juhu

  6. git reset .

    \=> fatal: 'HEAD' konnte nicht als gültige Referenz aufgelöst werden.

Es stellt sich außerdem heraus, dass es einen protokollierten Fehler in der Mailingliste gegen die Hilfslosigkeit dieser Vorgehensweise.

Und dass die richtige Lösung genau dort in der Git-Status-Ausgabe zu finden war (die ich natürlich als "Mist" abgetan habe)

...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...

Und die Lösung ist in der Tat die Verwendung von git rm --cached FILE .

Beachten Sie die Warnungen an anderer Stelle hier - git rm löscht Ihre lokale Arbeitskopie der Datei, aber no wenn Sie -cached . Hier ist das Ergebnis von git help rm :

-cached Verwenden Sie diese Option, um Pfade nur aus dem Index zu entfernen. Arbeitsbaumdateien, ob geändert oder nicht, bleiben erhalten.

Ich fahre fort mit

git rm --cached .

um alles zu entfernen und neu zu beginnen. Hat aber nicht funktioniert, denn während add . rekursiv ist, stellt sich heraus rm braucht -r zu rekursieren. Seufz.

git rm -r --cached .

Okay, jetzt bin ich wieder da, wo ich angefangen habe. Das nächste Mal werde ich -n um einen Probelauf zu machen und zu sehen, was hinzugefügt werden soll:

git add -n .

Ich habe alles an einem sicheren Ort verstaut, bevor ich mich auf git help rm über die --cached nichts zu zerstören (und was, wenn ich es falsch geschrieben habe).

0 Stimmen

Tut nicht einfach "git reset" ohne . das, was Sie wollen, oder übersehe ich etwas?

30 Stimmen

Hah. Ich habe das gleiche Verfahren angewandt. Nur habe ich aufgegeben und gesagt rm -rf .git , git init weil ich kein Vertrauen in die git rm --cached um meine Arbeitskopie zu behalten. Das sagt ein wenig darüber aus, dass Git an manchen Stellen immer noch übermäßig komplex ist. git unstage sollte einfach ein Standardbefehl sein, es ist mir egal, ob ich ihn als Alias hinzufügen kann.

3 Stimmen

Ich habe dies getan und alle meine anderen vorhandenen Dateien - unverändert - aus dem Git-Backup gelöscht. Durch das erneute Hinzufügen wird alles größer und der korrekte Verlauf wird zerstört. Git ist ein völlig unfertiges Projekt.

634voto

Paul Beckingham Punkte 13955

Wenn Sie tippen:

git status

In Git erfahren Sie, was sich im Stadium befindet usw., einschließlich Anweisungen, wie Sie das Stadium aufheben können:

use "git reset HEAD <file>..." to unstage

Ich finde, dass Git mich in solchen Situationen ziemlich gut dazu anspornt, das Richtige zu tun.

Hinweis: In neueren Git-Versionen (1.8.4.x) hat sich diese Meldung geändert:

(use "git rm --cached <file>..." to unstage)

31 Stimmen

Die Meldung wird unterschiedlich ausfallen, je nachdem, ob die add Datei bereits verfolgt wurde (die add nur eine neue Version im Cache gespeichert - hier wird Ihre Nachricht angezeigt). Andernorts, wenn die Datei nicht vorher bereitgestellt wurde, wird Folgendes angezeigt use "git rm --cached <file>..." to unstage

0 Stimmen

Großartig! Die git reset HEAD <file> ist die einzige, die funktioniert, wenn Sie das Löschen einer Datei rückgängig machen wollen

4 Stimmen

Meine Git-Version 2.14.3 sagt git reset HEAD zu enttarnen.

315voto

takeshin Punkte 46602

Zur Klarstellung: git add verschiebt Änderungen aus dem aktuellen Arbeitsverzeichnis in das Bereitstellungsraum (Index).

Dieser Vorgang wird als Inszenierung . Der natürlichste Befehl ist also Bühne die Änderungen (geänderte Dateien) ist das Naheliegendste:

git stage

git add ist nur ein einfacher zu schreibender Alias für git stage

Schade, dass es keine git unstage ni git unadd Befehle. Der entsprechende Befehl ist schwieriger zu erraten oder zu merken, aber er ist ziemlich offensichtlich:

git reset HEAD --

Wir können dafür einfach einen Alias erstellen:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

Und schließlich haben wir neue Befehle:

git add file1
git stage file2
git unadd file2
git unstage file1

Ich persönlich verwende noch kürzere Aliasnamen:

git a # For staging
git u # For unstaging

8 Stimmen

"bewegt"? Das würde bedeuten, dass es aus dem Arbeitsverzeichnis verschwunden ist. Das ist aber nicht der Fall.

10 Stimmen

Warum ist das so offensichtlich?

0 Stimmen

Eigentlich, git stage ist der Alias für git add was der historische Befehl ist, sowohl bei Git als auch bei anderen SCM. Er wurde im Dezember 2008 mit Commit 11920d28da im "Git's Git Repository" hinzugefügt, wenn ich das sagen darf.

225voto

leonbloy Punkte 68836

Eine Ergänzung zur akzeptierten Antwort: Wenn Ihre irrtümlich hinzugefügte Datei sehr groß war, werden Sie wahrscheinlich feststellen, dass sie auch nach dem Entfernen aus dem Index mit ' git reset ', scheint es noch immer einen Platz in der .git Verzeichnis.

Dies ist kein Grund zur Beunruhigung; die Datei befindet sich zwar noch im Repository, aber nur als "loses Objekt". Sie wird nicht in andere Repositories kopiert (via clone, push), und der Platz wird irgendwann zurückgewonnen - wenn auch vielleicht nicht sehr bald. Wenn Sie besorgt sind, können Sie es ausführen:

git gc --prune=now

Update (im Folgenden versuche ich, einige Unklarheiten zu beseitigen, die sich aus den am meisten hochgestimmten Antworten ergeben können):

Welches ist also das wahre rückgängig machen de git add ?

git reset HEAD <file> ?

ou

git rm --cached <file> ?

Streng genommen, und wenn ich mich nicht irre: keine .

git add kann nicht rückgängig gemacht werden - sicher, im Allgemeinen.

Erinnern wir uns zunächst daran, was git add <file> tatsächlich tut:

  1. Si <file> war bisher nicht verfolgt , git add fügt es dem Cache hinzu mit ihrem aktuellen Inhalt.

  2. Si <file> war bereits verfolgt , git add speichert den aktuellen Inhalt (Snapshot, Version) in den Cache. In Git heißt diese Aktion immer noch hinzufügen. (nicht nur Update it), da zwei verschiedene Versionen (Snapshots) einer Datei als zwei verschiedene Elemente betrachtet werden: Wir fügen also tatsächlich ein neues Element in den Cache ein, das später übertragen wird.

Vor diesem Hintergrund ist die Frage etwas zweideutig:

Ich habe versehentlich Dateien mit dem Befehl...

Das Szenario des Auftraggebers scheint das erste zu sein (nicht verfolgte Datei), wir wollen, dass das "Rückgängigmachen" die Datei (nicht nur den aktuellen Inhalt) aus den verfolgten Elementen entfernt. Wenn dies der Fall ist, dann ist es in Ordnung, die git rm --cached <file> .

Und wir könnten auch git reset HEAD <file> . Dies ist im Allgemeinen vorzuziehen, da es in beiden Szenarien funktioniert: Es ermöglicht auch das Rückgängigmachen, wenn wir fälschlicherweise eine Version eines bereits verfolgten Artikels hinzugefügt haben.

Es gibt jedoch zwei Vorbehalte.

Erstens: Es gibt (wie in der Antwort dargelegt) nur ein Szenario, in dem git reset HEAD funktioniert nicht, aber git rm --cached macht: ein neues Repository (keine Übertragungen). Aber das ist wirklich ein praktisch irrelevanter Fall.

Zweitens: Seien Sie sich bewusst, dass git reset HEAD kann den zuvor zwischengespeicherten Dateiinhalt nicht auf magische Weise wiederherstellen, sondern synchronisiert ihn nur erneut mit dem HEAD. Wenn unsere fehlgeleitete git add eine frühere Staged-Uncommitted-Version überschrieben hat, können wir sie nicht wiederherstellen. Aus diesem Grund können wir streng genommen [*] nicht rückgängig machen.

Beispiel:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # First add of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # Stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # Oops we didn't mean this
$ git reset HEAD file.txt  # Undo?
$ git diff --cached file.txt  # No dif, of course. stage == HEAD
$ git diff file.txt   # We have irrevocably lost "version 2"
-version 1
+version 3

Natürlich ist dies nicht sehr kritisch, wenn wir dem üblichen faulen Arbeitsablauf folgen und "git add" nur für das Hinzufügen neuer Dateien verwenden (Fall 1) und neue Inhalte über die Übergabe aktualisieren, git commit -a Befehl.


* (Edit: das obige ist praktisch korrekt, aber es gibt immer noch ein paar leicht hakelige/umständliche Wege, um Änderungen wiederherzustellen, die bereitgestellt, aber nicht übertragen und dann überschrieben wurden - siehe die Kommentare von Johannes Matokic und iolsmit)

8 Stimmen

Streng genommen gibt es eine Möglichkeit, eine bereits bereitgestellte Datei, die mit git add ersetzt wurde, wiederherzustellen. Wie Sie erwähnen, erstellt git add ein Git-Objekt für diese Datei, das nicht nur beim vollständigen Entfernen der Datei, sondern auch beim Überschreiben mit neuen Inhalten zu einem losen Objekt wird. Es gibt jedoch keinen Befehl, um es automatisch wiederherzustellen. Stattdessen muss die Datei identifiziert und manuell oder mit speziell für diesen Fall geschriebenen Werkzeugen extrahiert werden (libgit2 erlaubt dies). Dies lohnt sich aber nur, wenn die Datei sehr wichtig und groß ist und nicht durch Bearbeiten der vorherigen Version wiederhergestellt werden kann.

5 Stimmen

Um mich zu korrigieren: Sobald die Lose-Objekt-Datei gefunden ist (verwenden Sie Metadaten wie Erstellungsdatum/-zeit) git cat-file zur Wiederherstellung des Inhalts verwendet werden kann.

10 Stimmen

Ein anderer Weg zu Änderungen wiederherstellen, die zwar bereitgestellt, aber nicht übertragen und dann überschrieben wurden z.B. durch einen anderen git add erfolgt über git fsck --unreachable die alle unerreichbaren Objekte auflistet, die Sie dann mit git show SHA-1_ID o git fsck --lost-found die baumelnde Objekte in .git/lost-found/commit/ o .git/lost-found/other/ je nach Typ. Siehe auch git fsck --help

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X