Änderungen an einer Datei in Git selektiv zurücksetzen oder auschecken?

86

Gibt es einen Befehl, mit dem Sie die Änderungen an einer Datei (oder Dateien) im Arbeitsverzeichnis teilweise rückgängig machen können?

Angenommen, Sie haben eine Datei häufig bearbeitet, stellen jedoch fest, dass Sie einige der Änderungen auf den festgeschriebenen Status zurücksetzen möchten, die anderen Änderungen jedoch nicht.

Ich stelle mir eine Option vor git checkout, die sehr ähnlich funktioniert git add -p, dh sie geht die Datei Stück für Stück durch und fragt, ob Sie sie behalten möchten oder nicht.

1800 INFORMATIONEN
quelle

Antworten:

84

Du könntest benutzen

git add -p <path>

um dann die Chunks zu inszenieren, die Sie in einer bestimmten Datei behalten möchten

git checkout -- <path>

Um die Änderungen am Arbeitsbaum zu verwerfen, die Sie nicht behalten möchten, überprüfen Sie die bereitgestellte Version der Datei.

Schließlich können Sie verwenden

git reset -- <path>

um die bereitgestellte Version der Datei auf die letzte festgeschriebene Version der Datei zurückzusetzen, damit Ihre Änderungen nicht bereitgestellt werden.

CB Bailey
quelle
Warum ist der Git-Befehl für diesen einfachen Anwendungsfall, den jedes andere Versionskontrollsystem nur als "Zurücksetzen" bezeichnet, so dunkel?
Jan Hettich
5
@Jan Können Sie mit dem revertBefehl anderer Versionskontrollsysteme auswählen, welche Änderungen in einer Datei rückgängig gemacht werden sollen? Wirklich fragen, da ich nur Erfahrung mit CVS und Git habe. In Git git checkout -- path/to/fileist ein einzelner Befehl, der alle Änderungen in dieser Datei zurücksetzt, dies ist jedoch nicht dasselbe wie oben.
michiakig
3
Es gibt auch git checkout --patchund git reset --patchwelche funktionieren wie git add --patchim neuesten Git.
Matt Connolly
2
@Rudie, das zeigt --normalerweise das Ende der Analyse von Optionen an und dass alle Argumente, die danach kommen, wörtlich interpretiert werden müssen. Dies bedeutet, dass Sie ./vor keinem Dateinamen, der mit einem Minuszeichen beginnt , etwas hinzufügen müssen , wenn der Dateiname danach kommt --.
Zrajm
Wenn ich git checkout --patchdas Diff benutze, scheint es rückwärts zu sein. Die Minus-Symbole fügen meiner Arbeitskopie Text hinzu, und die Plus-Symbole ENTFERNEN Zeilen aus meiner Arbeitskopie.
Felipe Alvarez
114

Mit Git-Version> = 1.7.1 kann ich

git checkout -p

Ich bin mir nicht sicher, wann diese Funktion eingeführt wurde.

thisgeek
quelle
11
Es ist erwähnenswert, dass Sie auch git reset -pÄnderungen aus dem Staging-Bereich / -Index selektiv entfernen können. Ich weiß auch nicht genau, in welcher Version von Git dies eingeführt wurde.
Dies ist die richtige Antwort, warum es nicht akzeptiert wurde.
Wukong
1
@wukong, weil diese Antwort 2 Jahre nach der Frage veröffentlicht wurde. In diesem Moment (2009) war Charles 'Antwort die beste Lösung
pomeh
8

git checkout $fileSetzt den Status der Datei $fileauf den zuletzt festgeschriebenen Status zurück. Ich denke, Sie können verwenden git checkout SHA-1 -- $file, um die Datei auf das von SHA-1 identifizierte Commit zurückzusetzen.

Koraktor
quelle
1
Ja, nicht genau das, was ich will, da ich einige der Änderungen, die ich in der Datei vorgenommen habe, behalten und die anderen
zurücksetzen
1

Wie viele Commits müssen Sie zurückgehen und auswählen? Wenn es nur eine ist, nehmen Sie vielleicht einen Zweig direkt davor, checken Sie die Datei aus, die Sie festgeschrieben haben, und git add -pfügen Sie sie dann hinzu, wie Sie es wollten. Dann können Sie zu Ihrem ursprünglichen Standort zurückkehren und die Datei in Ihrem temporären Zweig auschecken.

das ist:

git checkout -b temp troublesome-commit^
git checkout troublesome-commit -- path/to/file
git add -p path/to/file
git commit -c troublesome-commit
git checkout @{-1}
git checkout temp -- path/to/file
git commit path/to/file
git branch -D temp

Andere Alternativen sind das Zurückgehen und Bearbeiten des Commits mit git rebase -i(Markieren des Commits als edit, dann Ausführen eines git reset HEAD^und Wiederholen des Commits, wenn es wieder in die Shell eingefügt wird).

Wenn sich die Änderungen, aus denen Sie auswählen müssen, auf eine Reihe von Commits verteilen, ist es möglicherweise besser, sie als Patches (oder einen Patch, der alle abdeckt) zu extrahieren und den Patch von Hand zu bearbeiten, wobei Sie die Änderungen entfernen, die Sie behalten möchten. und Einspeisen des Restes in git apply --reverse.

araqnid
quelle
Ich möchte eigentlich nichts zurücksetzen, was festgeschrieben ist, ich möchte Änderungen rückgängig machen, die nur in meiner Arbeitskopie enthalten sind
1800 INFORMATION