Wie lösche ich nicht gepusste Git-Commits?

948

Ich habe mich versehentlich für den falschen Zweig entschieden. Wie lösche ich dieses Commit?

NullVoxPopuli
quelle

Antworten:

1811

Löschen Sie das letzte Commit und behalten Sie die von Ihnen geleistete Arbeit bei:

git reset --soft HEAD~1

Löschen Sie das letzte Commit und zerstören Sie die von Ihnen geleistete Arbeit :

git reset --hard HEAD~1
dbyrne
quelle
13
Stellen Sie sicher, dass HEAD auf den Zweig zeigt. (Überprüfen Sie es zuerst)
Frank Schwieterman
128
Und stellen Sie sicher, dass HEAD ~ 1 das Commit ist ... Sie könnten es auch tungit reset --hard origin
Daenyth
13
Gedankenlisten git remoteHerkunft für mich, git reset --hard originsagt fatal: ambiguous argument 'origin': unknown revision or path not in the working tree.. Warum?
trss
7
Das ist fantastisch. Ich habe gerade mein Leben gerettet.
NinjaBoy
2
git reset HEAD~1behält auch alle Ihre Änderungen bei, hinterlässt jedoch einen leeren Index, anstatt alles beizubehalten (wie es die --softOption tun würde).
Holloway
139

Ich frage mich, warum die beste Antwort, die ich gefunden habe, nur in den Kommentaren ist! ( von Daenyth mit 86 Stimmen )

git reset --hard origin

Dieser Befehl synchronisiert das lokale Repository mit dem Remote-Repository und entfernt alle Änderungen, die Sie an Ihrem lokalen Repository vorgenommen haben. Sie können auch Folgendes tun, um den genauen Zweig abzurufen, den Sie im Ursprung haben.

git reset --hard origin/<branch>
Ashkan Sirous
quelle
16
Vielen Dank dafür, erweitern Sie die Erklärung leicht: für einen bestimmten Zweig:git reset --hard origin/<branch>
klar
4
Oder git reset --soft origin/<branch>wenn Sie das Commit loswerden möchten, aber die lokale Arbeit beibehalten möchten.
Flusspferd
1
Ich verstehe fatal: ambiguous argument 'origin': unknown revision or path not in the working tree., Sie müssen den Zweig wie git reset --hard origin/feature/my-cool-stuff
Kip
Brillant! Dies funktioniert tatsächlich, im Gegensatz zu der "akzeptierten" Antwort, die nur den Kopf abnimmt und Sie hängen lässt.
Mae
55

Löschen Sie es nicht: für nur ein Commit git cherry-pick reicht aus.

Aber wenn Sie mehrere Commits in der falschen Filiale hatten, ist dies der Ortgit rebase --onto scheint das:

Angenommen, Sie haben Folgendes:

 x--x--x--x <-- master
           \
            -y--y--m--m <- y branch, with commits which should have been on master

, dann können Sie es markieren masterund verschieben, wo Sie sein möchten:

 git checkout master
 git branch tmp
 git checkout y
 git branch -f master

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- y branch, master branch

Setzen Sie den Zweig zurück, wo er hätte sein sollen:

 git checkout y
 git reset --hard HEAD~2 # ~1 in your case, 
                         # or ~n, n = number of commits to cancel

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- master branch
                ^
                |
                -- y branch

und verschieben Sie schließlich Ihre Commits (wenden Sie sie erneut an und machen Sie tatsächlich neue Commits)

 git rebase --onto tmp y master
 git branch -D tmp


 x--x--x--x--m'--m' <-- master
           \
            -y--y <- y branch
VonC
quelle
das war leider nicht die frage.
KatariaA
1
@KatariaA Dies ist eine gültige Alternative zum Löschen des Commits für den falschen Zweig und hilft anderen in derselben Situation (gutes Commit für den falschen Zweig).
VonC
14

Machen Sie ein git rebase -i FAR_ENOUGH_BACKund lassen Sie die Zeile für das Commit fallen, das Sie nicht möchten.

Hank Gay
quelle
6

Wenn Sie dieses Commit in einen anderen Zweig verschieben möchten, rufen Sie die SHA des betreffenden Commits ab

git rev-parse HEAD

Wechseln Sie dann den aktuellen Zweig

git checkout other-branch

Und cherry-pickdas verpflichten sichother-branch

git cherry-pick <sha-of-the-commit>
Alexander Groß
quelle
Nach meiner Erfahrung macht dies das Festschreiben aus dem ursprünglichen Zweig nicht rückgängig und erfordert daher das git reset --hard HEAD~1anschließende Festschreiben. Ich denke, die Verwendung von reset --softZweigstellenwechsel und erneutes Festschreiben hätte zusätzliche Arbeit gespart. Andererseits habe ich SourceTree verwendet, um die meisten meiner grundlegenden Aufgaben zu erledigen, und nur nach meinem Fehler eine Befehlszeile damit.
Jusopi
3

Als Referenz glaube ich, dass Sie Commits aus Ihrem aktuellen Zweig nicht nur mit git reset --hard, sondern auch mit dem folgenden Befehl "hart abschneiden" können:

git checkout -B <branch-name> <SHA>

Wenn Sie sich nicht für das Auschecken interessieren, können Sie den Zweig auf Folgendes einstellen:

git branch -f <branch-name> <SHA>

Dies wäre eine programmatische Methode, um beispielsweise Commits aus einem Zweig zu entfernen, um neue Commits in diesen Zweig zu kopieren (mithilfe von rebase).

Angenommen, Sie haben einen Zweig, der vom Master getrennt ist, weil Sie Quellen von einem anderen Speicherort genommen und in den Zweig kopiert haben.

Sie haben jetzt einen Zweig, in dem Sie Änderungen vorgenommen haben. Nennen wir ihn "Thema".

Sie erstellen jetzt ein Duplikat Ihres Themenzweigs und stützen es dann erneut auf den Quellcode-Speicherauszug, der sich im Zweig "Speicherauszug" befindet:

git branch topic_duplicate topic
git rebase --onto dump master topic_duplicate

Jetzt werden Ihre Änderungen in branch topic_duplicate basierend auf dem Startpunkt von "dump" erneut angewendet, aber nur die Commits, die seit "master" stattgefunden haben. Ihre Änderungen seit dem Master werden nun erneut auf "dump" angewendet, aber das Ergebnis endet in "topic_duplicate".

Sie können dann "dump" durch "topic_duplicate" ersetzen, indem Sie Folgendes tun:

git branch -f dump topic_duplicate
git branch -D topic_duplicate

Oder mit

git branch -M topic_duplicate dump

Oder einfach durch Entsorgen der Müllkippe

git branch -D dump

Vielleicht können Sie auch einfach nach dem Löschen des aktuellen "topic_duplicate" eine Auswahl treffen.

Ich versuche zu sagen, dass Sie, wenn Sie den aktuellen "doppelten" Zweig basierend auf einem anderen Vorfahren aktualisieren möchten, zuerst die zuvor "cherrypicked" Commits löschen müssen, indem Sie ein git reset --hard <last-commit-to-retain>oder ausführen git branch -f topic_duplicate <last-commit-to-retain>und dann die anderen Commits kopieren (vom Haupt- Commit) Themenzweig) entweder durch Umbasieren oder durch Kirschernte.

Das erneute Basieren funktioniert nur in einem Zweig, in dem bereits Commits vorhanden sind. Daher müssen Sie Ihren Themenzweig jedes Mal duplizieren, wenn Sie dies tun möchten.

Cherrypicking ist viel einfacher:

git cherry-pick master..topic

Die gesamte Sequenz läuft also auf Folgendes hinaus:

git reset --hard <latest-commit-to-keep>
git cherry-pick master..topic

Wenn Ihr Zweig mit doppelten Themen ausgecheckt wurde. Dadurch würden zuvor ausgewählte Informationen aus dem aktuellen Duplikat entfernt und alle Änderungen in "Thema" erneut auf Ihren aktuellen "Speicherauszug" (anderer Vorfahr) angewendet. Es scheint eine recht bequeme Möglichkeit zu sein, Ihre Entwicklung auf den "echten" Upstream-Master zu stützen, während Sie einen anderen "Downstream" -Master verwenden, um zu überprüfen, ob Ihre lokalen Änderungen auch noch für diesen gelten. Alternativ können Sie einfach ein Diff generieren und es dann außerhalb eines Git-Quellbaums anwenden. Auf diese Weise können Sie jedoch eine aktuelle modifizierte (gepatchte) Version beibehalten, die auf der Version Ihrer Distribution basiert, während Ihre eigentliche Entwicklung gegen den tatsächlichen Upstream-Master gerichtet ist.

Also nur um zu demonstrieren:

  • Durch das Zurücksetzen verweist Ihr Zweig auf ein anderes Commit (--hard überprüft auch das vorherige Commit, --soft behält hinzugefügte Dateien im Index bei (das würde beim erneuten Commit festgeschrieben werden) und der Standardwert (--mixed) nicht Überprüfen Sie das vorherige Commit (Löschen Ihrer lokalen Änderungen), aber der Index wird gelöscht (für das Commit wurde noch nichts hinzugefügt).
  • Sie können einfach einen Zweig zwingen, auf ein anderes Commit zu verweisen
  • Sie können dies tun, während Sie das Commit sofort überprüfen
  • Das Rebasieren funktioniert für Commits, die in Ihrer aktuellen Niederlassung vorhanden sind
  • Kirschernte bedeutet, von einem anderen Zweig zu kopieren

Hoffe das hilft jemandem. Ich wollte das umschreiben, aber ich kann es jetzt nicht schaffen. Grüße.

Xennex81
quelle
0

Der folgende Befehl hat für mich funktioniert, alle lokal festgeschriebenen Änderungen werden gelöscht und local wird auf den gleichen Wert wie Remote Origin / Master Branch zurückgesetzt.

Git Reset - harter Ursprung

Atul Sureka
quelle