Wie wird ein Merge-Commit zurückgesetzt, das bereits in den Remote-Zweig verschoben wurde?

git revert alleine funktioniert nicht. -m muss angegeben werden, und ich bin ziemlich verwirrt darüber.

Das hat schon mal jemand erlebt?

Die Option -m gibt die übergeordnete Nummer an . Dies liegt daran, dass ein Zusammenführungs-Commit mehr als ein Elternteil hat und Git nicht automatisch weiß, welches Elternelement die Hauptleitung war und welches Elternelement der Zweig war, den Sie auflösen möchten.

Wenn Sie einen Zusammenführungs-Commit in der Ausgabe von git log anzeigen, sehen Sie seine Eltern in der Zeile, die mit Merge beginnt:

 commit 8f937c683929b08379097828c8a04350b9b8e183 Merge: 8989ee0 7c6b236 Author: Ben James  Date: Wed Aug 17 22:49:41 2011 +0100 Merge branch 'gh-pages' Conflicts: README 

In dieser Situation erhalten Sie mit git revert 8f937c6 -m 1 den Baum, wie er in 8989ee0 , und git revert -m 2 8989ee0 git revert -m 2 setzt den Baum wieder ein, wie er in 7c6b236 .

Um die Eltern-IDs besser zu verstehen, können Sie Folgendes ausführen:

 git log 8989ee0 

und

 git log 7c6b236 

Hier ist ein vollständiges Beispiel in der Hoffnung, dass es jemandem hilft:

 git revert -m 1  git commit -m "Reverting the last commit which messed the repo." git push -u origin master 

Wobei der Commit-Hash der Zusammenführung ist, die Sie zurücksetzen möchten, und wie in der Erklärung dieser Antwort angegeben , gibt -m 1 an, dass Sie zu der Baumstruktur des ersten übergeordneten Elements zurückkehren möchten die Zusammenführung.

Die Zeile git commit ... schreibt im Wesentlichen Ihre Änderungen fest, während die dritte Zeile Ihre Änderungen öffentlich macht, indem Sie sie in den entfernten Zweig schieben.

Ben hat dir gesagt, wie man einen Merge-Commit rückgängig machen kann, aber es ist sehr wichtig , dass du das tust “erklärt, dass du niemals die Tree-Änderungen durch den Merge willst. Spätere Merges bringen daher nur Tree-Änderungen von Commits, die keine Vorfahren der zuvor zurückgesetzten Merge sind. Dies kann oder kann nicht sein, was Sie wollen. ” (git-merge man-Seite) .

Eine Artikel- / Mailinglisten-Nachricht, die von der Man-Page verlinkt ist, beschreibt die Mechanismen und Überlegungen, die involviert sind. Stellen Sie nur sicher, dass Sie verstehen, dass Sie die Verzweigung nicht einfach später erneut zusammenführen können, wenn Sie den Zusammenführungs-Commit rückgängig machen, und erwarten, dass die gleichen Änderungen zurückkommen.

Sie können diese Schritte ausführen, um die inkorrekten Commits rückgängig zu machen oder Ihre Remote-Verzweigung auf HEAD / State zurückzusetzen.

  1. Überprüfe den entfernten Zweig zum lokalen Repo.
    git checkout development
  2. Kopieren Sie den Commit-Hash (dh die ID des Commits unmittelbar vor dem falschen Commit) von git log git log -n5

    Ausgabe:

    commit 7cd42475d6f95f5896b6f02e902efab0b70e8038 “Verzweigung ‘falsch-commit’ in ‘Entwicklung'”
    commit f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 “das ist ein falsches Commit”
    commit 3779ab50e72908da92d2cfcd72256d7a09f446ba “das ist das richtige Commit”

  3. Setzen Sie den Zweig auf den im vorherigen Schritt kopierten Hash-Wert zurück
    git reset (ie 3779ab50e72908da92d2cfcd72256d7a09f446ba)

  4. Führen Sie den git status , um alle Änderungen anzuzeigen, die Teil des falschen Commits waren.
  5. Führen Sie einfach git reset --hard , um alle Änderungen git reset --hard zu machen.
  6. Drücken Sie Ihre lokale Zweigstelle auf “remote” und beachten Sie, dass Ihr Commit-Verlauf so sauber ist, wie er war, bevor er verschmutzt wurde.
    git push -f origin development
 git revert -m 1  

Manchmal ist der effektivste Weg zum Zurücksetzen ein Schritt zurück und ersetzen.

git log

Verwenden Sie den zweiten Commit-Hash (vollständiger Hash, den Sie zurückschreiben möchten, bevor der Fehler aufgelistet wird) und rebranchieren Sie von dort aus.

git checkout -b newbranch

Löschen Sie dann den alten Zweig, kopieren Sie den neuen Zweig an seiner Stelle und starten Sie von dort aus neu.

 git branch -D oldbranch git checkout -b oldbranch newbranch 

Wenn es gesendet wurde, dann lösche den alten Zweig aus allen Repositories, schiebe den wiederhergestellten Zweig auf den zentralsten und ziehe ihn zurück nach unten.

Um das Protokoll sauber zu halten, da nichts passiert ist (mit einigen Nachteilen bei diesem Ansatz (aufgrund von Push-f)):

 git checkout  git reset --hard  git push -f origin HEAD: 

‘commit-hash-before-merge’ kommt vom Protokoll (git log) nach der Zusammenführung.

Ich fand einen umgekehrten Patch zwischen zwei bekannten Endpunkten und die Anwendung dieses Patches würde funktionieren. Dies setzt voraus, dass Sie Snapshots (Tags) aus Ihrem Master-Zweig oder sogar eine Sicherungskopie Ihres Master-Zweigs say master_bk_01012017 erstellt haben.

Sagen wir, der Code-Zweig, den du in den Master eingebunden hast, war mein Codebranch.

  1. Kasse Master.
  2. Erstellen Sie ein vollständiges binäres Reverse-Patch zwischen Master und Ihrem Backup. git diff --binary master..master_bk_01012017 > ~/myrevert.patch
  3. Überprüfen Sie Ihre Patch- git apply --check myrevert.patch
  4. Patch mit Sign-Off git am --signoff < myrevert.patch
  5. Wenn Sie diesen Code erneut git branch mycodebranch_fix müssen, sobald er behoben ist, müssen Sie den git branch mycodebranch_fix Master abzweigen und den Fix-Zweig git branch mycodebranch_fix git checkout mycodebranch_fix
  6. Hier müssen Sie den SHA-Schlüssel für den Rücksprung finden und den Rückumkehr- git revert [SHA]
  7. Jetzt können Sie Ihren mycodebranch_fix verwenden, um die Probleme zu beheben, zu committen und erneut in den Master zu migrieren, sobald Sie fertig sind.

Wie Ryan bereits erwähnt hat, könnte git revert die Verschmelzung auf der Straße erschweren, also ist git revert vielleicht nicht das, was du willst. Ich fand, dass die Verwendung des git reset --hard hier nützlicher ist.

Sobald Sie den Hard-Reset-Teil ausgeführt haben, können Sie Push zum entfernten Zweig zwingen, dh git push -f , wobei oft als origin . Von diesem Punkt können Sie wieder zusammenführen, wenn Sie möchten.