Rückgängigmachen eines "Git Push"

591

Folgendes habe ich an meinem angeblich stabilen Zweig getan ...

% git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded alpha-0.3.0 to master.
% git status
# On branch alpha-0.3.0
# Your branch is ahead of 'origin/alpha-0.3.0' by 53 commits.
#
nothing to commit (working directory clean)
% git push
Fetching remote heads...
  refs/
  refs/heads/
  refs/tags/
  refs/remotes/
'refs/heads/master': up-to-date
updating 'refs/heads/alpha-0.3.0'
  from cc4b63bebb6e6dd04407f8788938244b78c50285
  to   83c9191dea88d146400853af5eb7555f252001b0
    done
'refs/heads/unstable': up-to-date
Updating remote server info

Das war alles ein Fehler, wie ich später erkannte. Ich möchte diesen gesamten Prozess rückgängig machen und den Alpha-0.3.0-Zweig auf den ursprünglichen Wert zurücksetzen.

Was sollte ich tun?

Cyrus
quelle
dieser Stackoverflow-Beitrag vielleicht? stackoverflow.com/questions/134882/undoing-a-git-rebase
Steen
4
Es ist nicht wirklich die gleiche Situation. Das Rückgängigmachen einer Rebase ist ein lokales Repository-Szenario. Das Rückgängigmachen eines Git-Pushs umfasst ein Remote-Repository und kann je nach Zugriff schwieriger sein.
CB Bailey
Steen - du hast recht - ich hätte es wahrscheinlich tun sollen, nehme ich an. Ich dachte mir, dass das gesegnete Repository, aus dem alle ziehen, eher eine Verwaltungsaufgabe ist und daher hierher gehört, wo allgemeines clientseitiges Git eine Frage des Stapelüberlaufs ist.
Cyrus
Schnelle Klarstellung - Ich vermute, wenn Sie sich durch einen partiellen Hash-Wert auf ein Git-Commit beziehen , geht Git davon aus, dass Sie über das Commit sprechen, dessen Hash mit dieser Zeichenfolge beginnt.
Gershom

Antworten:

943

Sie müssen sicherstellen, dass keine anderen Benutzer dieses Repositorys die falschen Änderungen abrufen oder versuchen, auf den Commits aufzubauen, die entfernt werden sollen, da Sie den Verlauf zurückspulen möchten.

Dann müssen Sie die alte Referenz 'erzwingen'.

git push -f origin last_known_good_commit:branch_name

oder in deinem Fall

git push -f origin cc4b63bebb6:alpha-0.3.0

Möglicherweise haben Sie receive.denyNonFastForwardsdas Remote-Repository festgelegt. Wenn dies der Fall ist, erhalten Sie eine Fehlermeldung, die die Phrase enthält [remote rejected].

In diesem Szenario müssen Sie den Zweig löschen und neu erstellen.

git push origin :alpha-0.3.0
git push origin cc4b63bebb6:refs/heads/alpha-0.3.0

Wenn dies nicht funktioniert - möglicherweise weil Sie receive.denyDeletesfestgelegt haben, müssen Sie direkten Zugriff auf das Repository haben. Im Remote-Repository müssen Sie dann etwa den folgenden Installationsbefehl ausführen.

git update-ref refs/heads/alpha-0.3.0 cc4b63bebb6 83c9191dea8
CB Bailey
quelle
16
Eine perfekte und gut erklärte Antwort - vielen Dank. Für alle anderen, die darüber stolpern, habe ich aus akademischen Gründen beide der ersten beiden Ansätze ausprobiert und beide haben funktioniert - offensichtlich ist es der sauberste Ansatz, wenn der erste funktioniert. Wenn ich dich 10 Mal aufmuntern würde, würde ich es tun. :)
Cyrus
139
Zum schnellen Nachschlagen ist die erste Zeile hiergit push -f origin last_known_good_commit:branch_name
Philfreo
5
git push -f origin cc4b63bebb6: alpha-0.3.0 => dies hat mir geholfen. Hinweis alpha-0.3.0 ist der Filialname und cc4b63bebb6 ist die Commit-ID, auf die wir zurückgreifen möchten. Nachdem wir diesen Befehl ausgeführt haben, befinden wir uns in der Commit-ID cc4b63bebb6.
Kumar
22
Diese Lösung ist sehr gefährlich, wenn Sie in einem gemeinsam genutzten Repo arbeiten. Als bewährte Methode sollten alle Commits, die an ein freigegebenes Remote-Repo gesendet werden, als "unveränderlich" betrachtet werden. Verwenden Sie stattdessen 'git revert
Saboosh
1
jww - im Vergleich zu allem anderen ist git das funktionsreichste und effizienteste verfügbare Tool zur Quellcodeverwaltung. Jedes Team benutzt es anders. Es lohnt sich, ein Wochenende mit einem neuen Repository zu verbringen und alle gängigen Szenarien durchzugehen. Sobald Sie einige Zeit damit verbracht haben, ist die Entwicklung viel weniger stressig.
user1491819
165

Ich glaube, dass Sie dies auch tun können:

git checkout alpha-0.3.0
git reset --hard cc4b63bebb6
git push origin +alpha-0.3.0

Dies ist der letzten Methode sehr ähnlich, außer dass Sie nicht im Remote-Repo herumspielen müssen.

Benny Wong
quelle
9
Dies hat auch bei mir funktioniert, aber es ist erwähnenswert, dass dadurch die Geschichte auf der Fernbedienung "neu geschrieben" wird. Dies kann sein, was Sie wollen, aber es kann nicht sein!
Tom
3
+1 für diese Antwort, die mir wirklich geholfen hat. Ich wollte auch hinzufügen (und die Dinge klarstellen), dass die Commit-ID (die nach dem --hardParameter " " steht) die ID des Commits sein sollte, auf das Sie Ihren Zweig zurücksetzen möchten.
Michael Dautermann
1
Die Geschichte wurde gut umgeschrieben ... jeder, der die Änderungen hätte vornehmen können, ich habe nur dafür gesorgt, dass sie eine gemacht haben, git reset --hard [commit_id]damit wir uns nicht mit dem Raum-Zeit-Kontinuum anlegen.
Alien Life Form
9
Wofür ist das + in "git push origin + alpha-0.3.0"?
Jpierson
1
@jpierson +erzwingt den Push ähnlich wie -f(jedoch etwas anders: stackoverflow.com/a/25937833/1757149 ). Wenn Sie es ohne versuchen, schlägt git push origin alpha-0.3.0der Push fehl : Updates were rejected because the tip of your current branch is behind.
A__
106

git revert ist weniger gefährlich als einige der hier vorgeschlagenen Ansätze:

prompt> git revert 35f6af6f77f116ef922e3d75bc80a4a466f92650
[master 71738a9] Revert "Issue #482 - Fixed bug."
 4 files changed, 30 insertions(+), 42 deletions(-)
prompt> git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
prompt>

Ersetzen Sie 35f6af6f77f116ef922e3d75bc80a4a466f92650 durch Ihr eigenes Commit.

neoneye
quelle
2
Wie komme ich auf die ID 35f6af6f77f116ef922e3d75bc80a4a466f92650? Diese Antwort wäre besser, wenn Sie das erklären könnten.
Volomike
2
@Volomike (und Googeln Entwickler der Zukunft), beschreibt diese Frage viele Möglichkeiten, um es zu erhalten: Versionskontrolle und Hash-Frage auf SO
Jaime
Dies ist die richtige Antwort, da Sie mit "git reset" nicht pushen können sollten (Aktualisierungen wurden abgelehnt, weil sich die Spitze Ihres aktuellen Zweigs hinter dem entfernten Gegenstück befindet) oder Sie das Ziehen erzwingen müssen, das nicht wirklich sauber ist.
Thomas Decaux
Das hat bei mir funktioniert. Seien Sie jedoch vorsichtig, da durch Zurücksetzen alle Änderungen in Ihren lokalen Dateien zurückgesetzt werden.
user1941537
Ich habe mich mehrmals für diesen Ansatz entschieden, aber ich verwende auch git rebase -i <id-before-last-good-commit>, um eine interaktive Rebase durchzuführen und den Verlauf zu bereinigen, wie hier vorgeschlagen, stackoverflow.com/questions/5189560/… .
Ernesto Allely
35

Die akzeptierte Lösung (von @charles bailey) ist sehr gefährlich, wenn Sie in einem gemeinsamen Repo arbeiten.

Als bewährte Methode sollten alle Commits, die an ein freigegebenes Remote-Repo gesendet werden, als "unveränderlich" betrachtet werden. Verwenden Sie stattdessen 'git revert': http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#fixing-mistakes

https://git-scm.com/book/be/v2/Git-Basics-Undoing-Things

Saboosh
quelle
Was genau sind die Anweisungen, die Sie verschreiben? Sie scheinen nur alte Links zu haben.
JWW
32

Eine Möglichkeit, dies zu tun, ohne die gewünschten Änderungen zu verlieren:

git reset cc4b63b 
git stash
git push -f origin alpha-0.3.0
git stash pop

Dann können Sie die Dateien auswählen, die Sie pushen möchten

curmil
quelle
19

Ein anderer Weg, dies zu tun:

  1. Erstellen Sie einen weiteren Zweig
  2. Überprüfen Sie das vorherige Commit für diesen Zweig mit "git checkout".
  3. Schieben Sie den neuen Zweig.
  4. lösche den alten Zweig und drücke auf Löschen (benutze git push origin --delete <branch_name>)
  5. Benennen Sie den neuen Zweig in den alten Zweig um
  6. erneut drücken.
Rushabh Mehta
quelle
2
Dieser sieht aus wie eine echte Lösung, wenn Sie bereits falsche Commits im Repo haben
Illarion Kovalchuk
17
git push origin +7f6d03:master

Dadurch wird Ihr Repo auf die angegebene Commit-Nummer zurückgesetzt

ireshika piyumalie
quelle
2
Dies ist die einfachste Antwort. Sie sind ein Live-Retter.
Ekundayo Segen Funminiyi
2
Denken Sie daran, dass Ihre lokalen Dateien dadurch nicht zurückgesetzt werden.
K-Gun
11

Rückgängigmachen mehrerer Commits Git-Reset --hard 0ad5a7a6 (Geben Sie einfach den Commit-SHA1-Hash an)

Machen Sie das letzte Commit rückgängig

git reset --hard HEAD ~ 1 (Änderungen am letzten Commit werden entfernt) git reset --soft HEAD ~ 1 (Änderungen am letzten Commit sind als nicht festgeschriebene lokale Änderungen verfügbar)

Jaymin
quelle
9

Szenario 1 : Wenn Sie das letzte Commit rückgängig machen möchten, z. B. 8123b7e04b3, finden Sie unten den Befehl (dies hat bei mir funktioniert):

git push origin +8123b7e04b3^:<branch_name>

Die Ausgabe sieht wie folgt aus:

Total 0 (delta 0), reused 0 (delta 0)
To https://testlocation/code.git
 + 8123b7e...92bc500 8123b7e04b3^ -> master (forced update)

Zusätzliche Informationen: Szenario 2 : In einigen Situationen möchten Sie möglicherweise das zurücksetzen, was Sie gerade rückgängig gemacht haben (im Grunde genommen das Rückgängigmachen rückgängig machen), und dann den folgenden Befehl verwenden:

git reset --hard 8123b7e04b3

Ausgabe:

HEAD is now at cc6206c Comment_that_was_entered_for_commit

Weitere Infos hier: https://github.com/blog/2019-how-to-undo-almost-anything-with-git

Barani r
quelle
Szenario 1 sollte die akzeptierte Antwort sein, da in der Frage nicht angegeben wurde, welches Commit gelöscht werden soll. Die akzeptierte Antwort löscht nur das letzte Commit. Diese Antwort löscht alle Festschreibungen.
Dominic Cerisano
0

Die vorhandenen Antworten sind gut und korrekt. Was ist jedoch, wenn Sie das pushaber rückgängig machen müssen :

  1. Sie möchten die Commits lokal beibehalten oder nicht festgeschriebene Änderungen beibehalten
  2. Sie wissen nicht, wie viele Commits Sie gerade gepusht haben

Verwenden Sie diesen Befehl, um die Änderung auf ref zurückzusetzen:

git push -f origin refs/remotes/origin/<branch>@{1}:<branch>
Vlad274
quelle
-2

Wenn Sie das letzte Commit ignorieren möchten, das Sie gerade in den Remote-Zweig verschoben haben: Dadurch wird das Commit nicht entfernt, sondern nur ignoriert, indem der Git-Zeiger auf das Commit verschoben wird, auf das HEAD ^ oder HEAD ^ 1 verweisen

git push origin +HEAD^:branch

Aber wenn Sie dieses Commit bereits gepusht haben und andere den Zweig gezogen haben. In diesem Fall ist es unerwünscht, den Verlauf Ihrer Niederlassung neu zu schreiben. Stattdessen sollten Sie dieses Commit zurücksetzen:

git revert <SHA-1>
git push origin branch
mkebri
quelle
1
Ja! Dies funktionierte wie ein Zauber bei der Arbeit mit Github. Vielen Dank.
Cukabeka
Die Frage ist über "Push", dann betrifft es den Remote-Zweig. Nein, um den HEAD um ein Commit zu verschieben, was bedeutet, dass das letzte gepusste Commit ignoriert wird. Tun Sie dies einfach: git push origin + HEAD ^: your_branch
mkebri