Wirf lokale Commits in Git weg

1469

Aufgrund einer schlechten Kirschernte ist mein lokales Git-Repository derzeit fünf Commits vor dem Ursprung und nicht in einem guten Zustand. Ich möchte all diese Verpflichtungen loswerden und von vorne beginnen.

Natürlich würde das Löschen meines Arbeitsverzeichnisses und das erneute Klonen dies tun, aber das erneute Herunterladen von allem von GitHub scheint übertrieben und meine Zeit nicht gut zu nutzen.

Vielleicht git revertist es das, was ich brauche, aber ich möchte nicht 10 Commits vor dem Ursprung (oder sogar sechs) abschließen, selbst wenn der Code selbst wieder in den richtigen Zustand versetzt wird. Ich möchte nur so tun, als wäre die letzte halbe Stunde nie passiert.

Gibt es einen einfachen Befehl, der dies erledigt? Es scheint ein offensichtlicher Anwendungsfall zu sein, aber ich finde keine Beispiele dafür.


Beachten Sie, dass es bei dieser Frage speziell um Commits geht , nicht um:

  • nicht verfolgte Dateien
  • nicht inszenierte Änderungen
  • inszenierte, aber nicht festgeschriebene Änderungen
David Moles
quelle

Antworten:

2470

Wenn Ihre überschüssigen Commits nur für Sie sichtbar sind, können Sie einfach git reset --hard origin/<branch_name> dorthin zurückkehren, wo sich der Ursprung befindet. Dadurch wird der Status des Repositorys auf das vorherige Commit zurückgesetzt und alle lokalen Änderungen werden verworfen.

Wenn Sie a git revertausführen, werden neue Commits erstellt, um alte Commits so zu entfernen , dass die Geschichte aller gesund bleibt.

Ben Jackson
quelle
91
git reset --hard <commit hash, branch, or tag>Wenn Sie zu einer anderen Referenz als einer Remote-Verzweigung wechseln möchten.
Sam Soffes
55
Nur um klar zu sein, wenn Sie nicht masteran einem anderen Zweig arbeiten, sollten Sie laufengit reset --hard origin/<your-branch-name>
Zoltán
33
Dadurch werden nicht nur lokale Commits verworfen, sondern auch alles in Ihrem Arbeitsbaum (dh Ihre lokalen Dateien) weggeworfen. Wenn Sie nur die Verpflichtung
aufheben
3
Möglicherweise möchten Sie danach einen Abruf durchführen. Dadurch wurde der Zähler für die Anzahl der Commits, die darauf warten, verschoben zu werden, in SourceTree behoben.
Stan
2
git reset --hard origin/<branch_name>Dadurch wird auch die Projektkonfiguration zurückgesetzt. Achten Sie also darauf. Ich habe eine große .cfgDatei, die auf die Standardeinstellungen zurückgesetzt wurde. Ich musste wieder Stunden damit verbringen.
MAC
271

Löschen Sie einfach Ihren lokalen Hauptzweig und erstellen Sie ihn wie folgt neu:

git branch -D master
git checkout origin/master -b master
Ramon Zarazua B.
quelle
2
Dies funktioniert gut, wenn das Zurückverfolgen Ihrer Änderungen zu viel Zeit kosten würde, was mir nach einigen Rebases passiert ist.
Über
1
Nützlich für Teilbaum-Pull / Push-Probleme unter Teammitgliedern!
Jorge Orpinel
Dies ist perfekt, wenn Sie einen Zweig wiederherstellen möchten, anstatt nur den Master.
Vladimir Ralev
1
Dies ist kein guter Weg, um ein einzelnes lokales Commit zu löschen. Besser zu benutzengit reset --hard origin/<branch_name>
Kirit Vaghela
1
Vielleicht funktioniert diese Lösung, aber das bedeutet nicht, dass es die richtige ist.
Adly
202

Versuchen:

git reset --hard <the sha1 hash>

um deinen Kopf dorthin zurückzusetzen, wo du sein willst. Verwenden Sie gitk, um zu sehen, bei welchem ​​Commit Sie sein möchten. Sie können auch innerhalb von gitk zurücksetzen.

Anders Zommarin
quelle
5
Dieses B / C hat nützliche Informationen erhalten, aber Ben Jacksons Antwort erhält das Häkchen, um genau das zu lösen, was ich wollte - auf eine Weise, bei der ich nicht nach Commit-Hashes suchen musste. :)
David Moles
2
Dies ist der Zeitpunkt, an dem Ihr neuer Zweig noch nie zum Ursprung gebracht wurde
Januar
126

Löschen Sie das letzte Commit:

git reset --hard HEAD~1

Löschen Sie das letzte Commit, ohne die von Ihnen geleistete Arbeit zu zerstören:

git reset --soft HEAD~1

James L.
quelle
5
Nützliche Antwort. Vielen Dank! Ich habe Git Reset - Soft Origin / Master
Tarun Kumar
2
@ TarunKumar DANKE! Ich verwende die VS-Integration, und Ihre Lösung war die einzige Möglichkeit, eine Reihe von Zusammenführungs-Commits zu löschen, die ich nicht in einem Zweig haben wollte, für den ich keine Berechtigung zum Einchecken hatte.
DVK
Vielen Dank, genau das, wonach ich gesucht habe. "Git reset --soft HEAD ~ 1" hat die Arbeit erledigt, da ich mich unbeabsichtigt verpflichtet habe und zurücksetzen wollte, aber andere Dateien hatte, die ich nach dem Zurücksetzen nicht zerstören wollte.
edvard_munch
47

Wenn Sie die Atlassian SourceTree- App verwenden, können Sie die Option zum Zurücksetzen im Kontextmenü verwenden.

Geben Sie hier die Bildbeschreibung ein

Muruge
quelle
42

Bei Ihrem Zweigversuch:

git reset --hard origin/<branch_name>

Überprüfen Sie die Umkehrung (auf den Status ohne lokale Festschreibungen) mit " git log" oder " git status".

Parasrish
quelle
1
@Troyseph: Alle oben aufgeführten Antworten habe ich so wie sie sind versucht und das Szenario nicht behoben. Der generische Ansatz, der in keiner der obigen Antworten dargestellt wurde, wurde hier beantwortet.
Parasrish
3
Die akzeptierte Antwort ist dieselbe wie Ihre, abzüglich des generischen Zweignamens, und in den Kommentaren sagt @Zoltan ausdrücklichJust to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph
1
Dies ist meiner Meinung nach die beste Antwort.
Dwjohnston
21

git reset --hard @{u}* löscht alle Ihre lokalen Änderungen im aktuellen Zweig, einschließlich Commits. Ich bin überrascht, dass dies noch niemand gepostet hat, wenn man bedenkt, dass Sie nicht nachschlagen müssen, zu welchen Zweigen Sie zurückkehren oder mit ihnen spielen möchten.

* Das heißt, auf den aktuellen Zweig @{upstream}zurücksetzen origin/<branchname>- gelegentlich , aber nicht immer

Kevin Chen
quelle
1
Einige Muscheln wie Fische interpretieren das "@", sodass Sie möglicherweise das "@ {u}" in Anführungszeichen setzen müssen, z. B. "git reset --hard" @ {u} ". Wie auch immer, guter Fund!
Tryse
Fantastische Antwort ist fantastisch
Marko
1
Wie druckt man den Wert von @ {u}?
Philip Rego
12

Um die SHA-1-ID des Commits zu sehen / zu erhalten, möchten Sie auch zurückkehren

gitk --all

Zurück zu diesem Commit

git reset --hard sha1_id

!Hinweis. Alle Commits, die nach diesem Commit vorgenommen wurden, werden gelöscht (und alle Ihre Änderungen am Projekt). Klonen Sie das Projekt also zuerst besser in einen anderen Zweig oder kopieren Sie es in ein anderes Verzeichnis.

Nikolaus
quelle
Dies ist ideal für Situationen, in denen die Fernbedienung nicht mehr verfügbar ist und lediglich ein lokales Commit durchgeführt werden muss. Gitk ist großartig - war sich dessen vorher nicht bewusst.
TheRiley
Wenn Sie bereits in gitk sind, können Sie auch einfach mit der rechten Maustaste auf das Commit klicken und "Zweig XY auf hier zurücksetzen" auswählen.
mkrieger1
Und die neueren Commits werden nicht sofort gelöscht. Es gibt nur noch keinen Zweig, der auf sie verweist (denken Sie daran, ein Zweig ist nichts anderes als ein "Lesezeichen" für ein bestimmtes Commit).
mkrieger1
9

Ich hatte eine Situation, in der ich ein Commit entfernen wollte, das nicht gepusht wurde, aber das Commit war vor einem anderen. Dazu habe ich den folgenden Befehl verwendet

git rebase -i HEAD~2 -> Die letzten beiden Commits werden neu gestartet

Und ich habe 'drop' für die Commit-Signatur verwendet, die ich entfernen wollte.

Robert
quelle
9

Nicht verfolgte Dateien entfernen (nicht festgeschriebene lokale Änderungen)

git clean -df

Löschen Sie alle lokalen Commits dauerhaft und erhalten Sie das neueste Remote-Commit

git reset --hard origin/<branch_name>
ElasticCode
quelle
8

Für lokale Commits, die nicht gepusht werden, können Sie auch git rebase -iein Commit löschen oder quetschen.

Nikhil Katre
quelle
1
Ich weiß, dass dies möglicherweise nicht die kürzeste Lösung ist, aber ich habe Sie positiv bewertet, da IMHO git rebase -ieine allgemeinere Methode zur Lösung vieler ähnlicher Probleme darstellt und in einer Vielzahl von Situationen hilfreich sein kann.
Stefan Marinov
1
Verwenden Sie das dropSchlüsselwort (anstatt eine Zeile zu löschen), wenn Sie alle Commits entfernen, um zu vermeiden, dass die Rebase abgebrochen wird.
Michal Čizmazia
6

Eine einfache Lösung besteht darin, den HEAD des lokalen Hauptzweigs dem HEAD des Ursprungs- / Hauptzweigs zuzuordnen

git reset --hard origin/master

PS: origin / master - ist ein entfernter Zeiger auf den Master-Zweig. Sie können den Master durch einen beliebigen Filialnamen ersetzen

narwanimonisch
quelle
4

Bevor wir antworten, fügen wir einige Hintergrundinformationen hinzu und erklären, was dies ist HEAD. da einige der folgenden Optionen zu einem abgenommenen Kopf führen

First of all what is HEAD?

HEADist einfach ein Verweis auf das aktuelle Commit (aktuell) in der aktuellen Verzweigung.
Es kann immer nur eine einzige HEADgeben. (ausgenommen git worktree)

Der Inhalt von HEADwird darin gespeichert .git/HEADund enthält die 40 Bytes SHA-1 des aktuellen Commits.


detached HEAD

Wenn Sie sich nicht im letzten Commit befinden, bedeutet dies, dass HEADauf ein vorheriges Commit in der Geschichte verwiesen wird detached HEAD.

Geben Sie hier die Bildbeschreibung ein

In der Befehlszeile sieht es so aus: SHA-1 anstelle des Zweignamens, da der HEADnicht auf die Spitze des aktuellen Zweigs zeigt

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Einige Optionen zur Wiederherstellung nach einem abgetrennten KOPF:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Dadurch wird ein neuer Zweig ausgecheckt, der auf das gewünschte Commit verweist.
Dieser Befehl checkt zu einem bestimmten Commit aus.
An diesem Punkt können Sie einen Zweig erstellen und ab diesem Punkt mit der Arbeit beginnen.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Sie können das auch immer verwenden reflog.
git reflogzeigt jede Änderung an, die das aktualisiert hat, HEADund das Auschecken des gewünschten Reflog-Eintrags setzt HEADdiesen Commit zurück.

Jedes Mal, wenn der KOPF geändert wird, wird ein neuer Eintrag in der reflog

git reflog
git checkout HEAD@{...}

Dadurch kehren Sie zu Ihrem gewünschten Commit zurück

Geben Sie hier die Bildbeschreibung ein


git reset --hard <commit_id>

"Bewegen" Sie Ihren HEAD zurück zum gewünschten Commit.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Hinweis: ( Seit Git 2.7 ) können
    Sie auch das verwenden git rebase --no-autostash.

git revert <sha-1>

"Rückgängig machen" des angegebenen Commits oder Commit-Bereichs.
Der Befehl zum Zurücksetzen "macht" alle Änderungen rückgängig, die im angegebenen Commit vorgenommen wurden.
Ein neues Commit mit dem Undo-Patch wird festgeschrieben, während das ursprüngliche Commit ebenfalls im Verlauf verbleibt.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Dieses Schema zeigt, welcher Befehl was tut.
Wie Sie dort sehen können, reset && checkoutändern Sie die HEAD.

Geben Sie hier die Bildbeschreibung ein

CodeWizard
quelle
3

Für diejenigen, die an der Visual Studio-Lösung interessiert sind, ist hier die Übung:

  1. Stellen Sie im Team ExplorerFenster eine Verbindung zum Ziel-Repo her.
  2. Dann von der Branchesrechten Maustaste auf den Zweig von Interesse und wählen View history.
  3. Klicken Sie mit der rechten Maustaste auf ein Commit im HistoryFenster und wählen Sie Reset -> Delete changes (--hard).

Dadurch werden Ihre lokalen Commits verworfen und der Status Ihres Repos auf das ausgewählte Commit zurückgesetzt. Dh Ihre Änderungen, nachdem Sie das Repo gezogen haben, gehen verloren.

Bozhidar Stoyneff
quelle
2

Wenn Ihre Niederlassung vor 'origin/XXX um 5 Commits ' liegt.

Sie können Folgendes ausgeben:

git reset --hard HEAD~5

Und es sollte die letzten 5 Commits entfernen.

Ha Choo
quelle
0
git reset --hard <SHA-Code>

Dies ist nützlich, wenn Sie auf Ihrer lokalen Kopie einige Fehler gemacht haben, die Sie sicherstellen möchten, dass sie nicht versehentlich in Ihren Remote-Zweig verschoben werden.

Den SHA-Code erhalten Sie, indem Sie in der webVersion Ihres Git-Dashboards nach dem letzten Commit für den Zweig suchen.

Auf diese Weise können Sie mit dem letzten Commit in der Verzweigung synchronisiert werden.

git pullNachdem Sie den Hard-Reset erfolgreich abgeschlossen haben, können Sie bestätigen, dass nichts Neues zu synchronisieren ist, dh Sie erhalten die Meldung.

Ihre Niederlassung ist auf dem neuesten Stand Origin/<Branch Name>

Sameer Ashraf
quelle
0

Wenn Sie Ihr lokales Repo völlig durcheinander bringen, können Sie lokale Commits in Git zuverlässig ...

  1. Verwenden Sie "git config --get remote.origin.url", um die URL des Remote-Ursprungs abzurufen
  2. Benennen Sie den lokalen Git-Ordner in "my_broken_local_repo" um.
  3. Verwenden Sie "git clone <url_from_1>", um eine neue lokale Kopie des Remote-Git-Repositorys abzurufen

Nach meiner Erfahrung geht Eclipse gut mit der sich verändernden Welt um. Möglicherweise müssen Sie jedoch betroffene Projekte in Eclipse auswählen und bereinigen, um Eclipse zu zwingen, sie neu zu erstellen. Ich denke, andere IDEs müssen möglicherweise ebenfalls neu erstellt werden.

Ein Nebeneffekt des oben beschriebenen Verfahrens besteht darin, dass Sie herausfinden, ob Ihr Projekt auf lokalen Dateien basiert, die nicht in git abgelegt wurden. Wenn Sie feststellen, dass Dateien fehlen, können Sie diese von "my_broken_local_repo" kopieren und zu git hinzufügen. Sobald Sie sicher sind, dass Ihr neues lokales Repo alles enthält, was Sie benötigen, können Sie "my_broken_local_repo" löschen.

Adam Gawne-Cain
quelle
0

Wenn Sie nur lokale Commits wegwerfen und die in Dateien vorgenommenen Änderungen beibehalten möchten, führen Sie
git reset @ ~ durch.
Andere Antworten betrafen den Hard-Reset

Ashish Banker
quelle