Wie kann ich ein zurückgesetztes Git-Commit "rückgängig machen"?

486

Was ist angesichts einer Änderung, die mit festgeschrieben commitund dann mit zurückgesetzt wurde revert, der beste Weg, um diese Rückgängigmachung rückgängig zu machen?

Idealerweise sollte dies mit einem neuen Commit erfolgen, um den Verlauf nicht neu zu schreiben.

JimmidyJoo
quelle
@phuclv ein Kommentar für mögliche Duplikate dort, Punkte hier. Man muss als original und man muss als doppelt markiert sein
John Demetriou
@ JohnDemetriou nein, die Frage, die eine bessere Reihe von Antworten hat, sollte offen gehalten werden. Zeit ist hier nicht relevant Wie sollen doppelte Fragen behandelt werden?
18.
Ich habe nicht über die Zeit gesagt. Ich habe gerade einen der beiden zu diesem Thema kommentiert
John Demetriou

Antworten:

385

Wenn Sie diese Änderung noch nicht vorangetrieben haben, git reset --hard HEAD^

Andernfalls ist das Zurücksetzen des Zurücksetzens vollkommen in Ordnung.

Ein anderer Weg ist zu git checkout HEAD^^ -- .und dann git add -A && git commit.

Adam Dymitruk
quelle
8
Beachten Sie, dass Sie, wenn Sie die Wiederherstellung rückgängig machen möchten, ohne die ursprünglichen Änderungen sofort auf den Hauptzweig anzuwenden, (1) den ursprünglichen Zweig wiederherstellen können, wenn er gelöscht wird, (2) auf den von Adam angegebenen Rücksetzzweig auf "Zurücksetzen" klicken und dann ( 3) Klicken Sie in der Kopfzeile des resultierenden PR auf "Bearbeiten" und ändern Sie den Zielzweig in den ursprünglichen Zweig anstelle des Masters. Jetzt kann Ihr ursprünglicher Zweig erneut zusammengeführt werden, um die zuvor zurückgesetzten Änderungen zu bewirken.
Pauljm
1
Bitte beachten Sie, dass dadurch alle Änderungen im Arbeitsbaum und im Index entfernt werden. Verwenden Sie git stash, um alle Änderungen zu speichern, die Sie nicht verlieren möchten.
Zpon
3
Was ist der Vorteil der Checkout && Commit-Methode? Es scheint, dass im allgemeinen Fall git cherry-pickoder alternativ git revertdie einfachsten Möglichkeiten sind, eine Rückstellung rückgängig zu machen.
Robert Jack Will
5
Ich denke, es wäre hilfreich zu zeigen, wie man: Otherwise, reverting the revert is perfectly fine.und dann auch zu erklären, was zu git checkout HEAD^^ -- .tun ist.
Todd
3
Guter Herr, verwenden Sie nicht git add -A... es sei denn, Sie möchten jede Datei zur Versionskontrolle hinzufügen, was höchstwahrscheinlich nicht das ist, was Sie wollen.
Kaitain
474

git cherry-pick <original commit sha>
Erstellt eine Kopie des ursprünglichen Commits und wendet das Commit im Wesentlichen erneut an

Das Zurücksetzen des Zurücksetzens bewirkt dasselbe mit einer unordentlicheren Festschreibungsnachricht:
git revert <commit sha of the revert>

Auf beide Arten können Sie den Verlauf git pushnicht überschreiben, da nach dem Zurücksetzen ein neues Commit erstellt wird.
Wenn Sie das Commit sha eingeben, benötigen Sie normalerweise nur die ersten 5 oder 6 Zeichen:
git cherry-pick 6bfabc

Stephan
quelle
61
Dies ist mit Sicherheit die eleganteste und vollständigste Lösung für die OP-Frage. Viel besser als die akzeptierte Antwort mit den Annahmen, dass sich das Revert-Commit im HEAD des Commit-Baums befindet. Die Operation hat auch ausdrücklich nach einer Lösung gefragt, die den Verlauf nicht neu schreibt, sodass die in der akzeptierten Antwort angebotene harte Lösung einfach falsch ist.
Timo
6
@Timo Zur Verdeutlichung enthält die akzeptierte Antwort die von mir verwendete Lösung ("Zurücksetzen des Zurücksetzens") und wurde innerhalb von Stunden nach meiner Frage veröffentlicht - ein klares 3 Jahre früher als diese Antwort. Daher das Häkchen.
JimmidyJoo
6
@ JimmyidyJoo Ich weiß, ich war 3 Jahre zu spät, ich wollte nur, dass Leute, die von einer Google-Suche hierher kommen, eine bessere Antwort sehen
Stephan
2
@Stephan Ja, aber noch einmal, um es zu verdeutlichen - es ist eine bessere Antwort, nur nicht die, mit der ich mein Problem gelöst habe. Ich habe nur kommentiert, warum das Häkchen dort ist, wo es ist. Frage an alle: schreibt die SO-Konvention vor, dass ich meine früheren Fragen "beibehalten" und Häkchen neu zuweisen soll, wenn neue Antworten eingehen?
JimmidyJoo
3
@ JimmyidyJoo Ich habe keine Ahnung von SO Konvention. Aber als Google-Sucher möchte ich wirklich, dass die bessere Antwort überprüft wird. Und würde mich über die Bemühungen eines jeden freuen, seine früheren Fragen aufrechtzuerhalten.
Paiman Roointan
28

Ein Revert-Commit ist genau wie jedes andere Commit in Git. Das heißt, Sie können es zurücksetzen, wie in:

git revert 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746

Das offensichtlich macht nur Sinn , wenn die Änderungen geschoben wurden, und vor allem , wenn Sie nicht Push auf die Zielmietstation zwingen können (das ist eine gute Idee für Dich ist Master - Zweig). Wenn die Änderung nicht übernommen wurde, wählen Sie einfach das Commit "Zurücksetzen" aus, entfernen Sie es oder entfernen Sie es einfach wie in anderen Beiträgen beschrieben.

In unserem Team haben wir eine Regel einen verwenden revert auf Revert Commits , die in dem Hauptzweig begangen wurden, in erster Linie die Geschichte sauber zu halten, so dass Sie sehen können , welche kehrt zu begehen , was:

      7963f4b2a9d   Revert "Revert "OD-9033 parallel reporting configuration"
      "This reverts commit a0e5e86d3b66cf206ae98a9c989f649eeba7965f.
                    ...
     a0e5e86d3b6    Revert "OD-9055 paralel reporting configuration"
     This reverts commit 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746.
                ...
     Merge pull request parallel_reporting_dbs to master* commit 
    '648d7d808bc1bca6dbf72d93bf3da7c65a9bd746'

Auf diese Weise können Sie die Geschichte verfolgen und die ganze Geschichte herausfinden, und selbst diejenigen, die das Erbe nicht kennen, können es selbst herausfinden. Wenn Sie dagegen Dinge auswählen oder neu aufbauen , gehen diese wertvollen Informationen verloren (es sei denn, Sie nehmen sie in den Kommentar auf).

Wenn ein Commit mehr als einmal zurückgesetzt und zurückgesetzt wird, wird dies offensichtlich ziemlich chaotisch.

Nestor Milyaev
quelle
14

Das Zurücksetzen des Zurücksetzens reicht aus

Zum Beispiel,

Wenn abcdefes sich um Ihr Commit handelt und ghijklum das Commit, das Sie beim Zurücksetzen des Commits haben abcdef, führen Sie Folgendes aus:

git revert ghijkl

Dadurch wird das Zurücksetzen rückgängig gemacht

rafee_que_
quelle
4

Es sieht für mich dumm aus. Aber ich war in der gleichen Situation gewesen und habe mich für rückgängig gemachte Commits zurückgezogen. Ich habe die Anzahl zurückgesetzt, also musste ich für jedes 'Zurücksetzen-Commit' zurücksetzen.

Jetzt sieht meine Commits-Geschichte ein bisschen komisch aus.

seltsame Geschichte

Es ist ein Haustierprojekt, also ist es in Ordnung. Aber für ein reales Projekt würde ich es vorziehen, zum letzten Commit zu gehen, bevor der gesamte zurückgesetzte Code in einem Commit und einem vernünftigeren Kommentar wiederhergestellt wird.

RredCat
quelle
4
Sie könnten an den Antworten auf eine andere Frage von mir interessiert sein
JimmidyJoo
2
Sie können das automatische Festschreiben vermeiden und auswählen, dass Sie eine Nachricht mit dem Flag --no-commit festschreiben, wenn Sie zurücksetzen und dann mit der entsprechenden Nachricht
festschreiben
Sie können auch mehrere Commit-IDs angeben, wenn Sie git revert verwenden (sie müssen meiner Meinung nach in der richtigen Reihenfolge sein).
Aalex Gabi
Kann ich das vom Github-Desktop aus tun?
Guillaume F.
4

So habe ich es gemacht:
Wenn der Zweig my_branchnamein einer Zusammenführung enthalten war, die zurückgesetzt wurde. Und ich wollte nicht zurückkehren my_branchname:

Ich mache zuerst eine git checkout -b my_new_branchnamevon my_branchname.
Dann mache ich einen git reset --soft $COMMIT_HASHWhere $COMMIT_HASHis Commit-Hash des Commits direkt vor dem ersten Commit von my_branchname(siehe git log).
Dann mache ich ein neues Commit. git commit -m "Add back reverted changes"
Dann schiebe ich den neuen Zweig hoch. git push origin new_branchname
Dann habe ich eine Pull-Anfrage für den neuen Zweig gestellt.

Drew LeSueur
quelle
Ein guter Weg, wenn es zu viele "Kirschpflücker" gibt. Ich verstehe nicht, warum diese Antwort so wenige positive Stimmen hat
Fundhor
2

Oder du könntest git checkout -b <new-branch>und git cherry-pick <commit>das vorher zum und git rebasefallen lassen revert. Pull-Anfrage wie zuvor senden.

Ryan Chou
quelle
1

Wenn Ihnen die Idee des "Zurücksetzens eines Zurücksetzens" nicht gefällt (insbesondere wenn dies bedeutet, dass für viele Commits Verlaufsinformationen verloren gehen), können Sie jederzeit die Git-Dokumentation zum Thema "Zurücksetzen eines fehlerhaften Zusammenführens" aufrufen .

Angesichts der folgenden Ausgangssituation

 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E   <-- fixed-up topic branch

(W ist Ihr anfängliches Zurücksetzen der Zusammenführung M; D und E sind Korrekturen an Ihrem anfänglich unterbrochenen Feature-Zweig / Commit)

Sie können jetzt einfach die Commits A bis E wiederholen, sodass keiner von ihnen zur rückgängig gemachten Zusammenführung "gehört":

$ git checkout E
$ git rebase --no-ff P

Die neue Kopie Ihrer Filiale kann jetzt wieder zusammengeführt masterwerden:

   A'---B'---C'------------D'---E'  <-- recreated topic branch
  /
 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E
NobodysNightmare
quelle
Gute Idee und danke für den Doc Link. Wir werden normalerweise mit master neu zusammengesetzt, bevor wir wieder zusammenführen, aber git scheint dann zu erkennen, dass A ', B', C 'die gleichen sind wie zuvor, und ich habe jetzt D, E nach W ( Pastebin ). Vorschläge zur Lösung dieses Problems?
Kristoffer Bakkejord
0

So erhalten Sie die nicht bereitgestellten und bereitgestellten Änderungen zurück, die nach einem Commit zurückgesetzt wurden:

git reset HEAD@{1}

So stellen Sie alle nicht bereitgestellten Löschungen wieder her:

git ls-files -d | xargs git checkout --
Richa Goyal
quelle