it-swarm.com.de

Einen Git Rebase rückgängig machen

Weiß jemand, wie man eine Git-Rebase leicht rückgängig macht?

Die einzige Möglichkeit, die Ihnen einfällt, ist, manuell vorzugehen:

  • git checkout der übergeordnete Commit für beide Niederlassungen 
  • erstellen Sie dann einen temporären Zweig
  • kirschpick alle Commits von Hand
  • ersetzen Sie den Zweig, in dem ich durch den manuell erstellten Zweig basierte

In meiner jetzigen Situation wird das funktionieren, weil ich leicht Commits aus beiden Branchen erkennen kann (einer war mein Zeug, der andere war der Stoff meines Kollegen).

Mein Ansatz erscheint mir jedoch als suboptimal und fehleranfällig (angenommen, ich hatte gerade mit zwei meiner eigenen Niederlassungen umgestaltet).

Irgendwelche Ideen?

Klarstellung: Ich spreche von einer Rebase, während der eine Reihe von Commits wiederholt wurden. Nicht nur einer.

2632
webmat

Der einfachste Weg wäre, das Head-Commit des Zweiges zu finden, wie es unmittelbar vor dem Start der Rebase im reflog ... war.

git reflog

und den aktuellen Zweig darauf zurücksetzen (mit den üblichen Vorbehalten, vor dem Zurücksetzen mit der --hard-Option absolut sicher zu sein).

Angenommen, das alte Commit war [email protected]{5} im ref-Protokoll:

git reset --hard [email protected]{5}

In Windows müssen Sie möglicherweise die Referenz angeben:

git reset --hard "[email protected]{5}"

Sie können den Verlauf des alten Kopfes des Kandidaten überprüfen, indem Sie einfach einen git log [email protected]{5} (Windows:git log "[email protected]{5}") ausführen.

Wenn Sie nicht pro Zweigreflogs deaktiviert haben, sollten Sie einfach git reflog [email protected]{1} tun können, da eine Rebase den Zweigkopf löst, bevor er wieder an den endgültigen Kopf anfügt. Ich würde dies noch einmal überprüfen, da ich dies in letzter Zeit nicht überprüft habe.

Standardmäßig sind alle Wiederherstellungsprotokolle für nicht bare Repositorys aktiviert:

[core]
    logAllRefUpdates = true
3645
CB Bailey

Eigentlich speichert rebase Ihren Startpunkt in ORIG_HEAD, so dass dies normalerweise so einfach ist wie:

git reset --hard ORIG_HEAD

Die Variablen reset, rebase und merge speichern jedoch Ihren ursprünglichen HEAD-Zeiger in ORIG_HEAD. Wenn Sie also seit der Rebase einen dieser Befehle ausgeführt haben, die Sie rückgängig machen möchten, müssen Sie das Reflog verwenden.

1297
Pat Notz

Die Antwort von Charles funktioniert, aber Sie möchten vielleicht Folgendes tun:

git rebase --abort

nach der reset aufräumen. 

Andernfalls erhalten Sie möglicherweise die Meldung "Interactive rebase already started".

338
Allan

git reflog zeigt Ihnen alle Änderungen vor und nach der Erneuerung und ermöglicht es Ihnen, die richtige zu finden, auf die zurückgesetzt werden soll. Aber ich bin überrascht, dass noch niemand diesen anderen einfachen Weg hier erwähnt hat:

Rebase belässt den alten Zustand als ORIG_HEAD, sodass Sie die letzte Rebase wiederherstellen können, indem Sie Folgendes ausführen:

git reset --hard ORIG_HEAD
80
Meligy

Das Zurücksetzen des Zweigs auf das unbenutzte Commit-Objekt seiner alten Spitze ist natürlich die beste Lösung, da der vorherige Zustand ohne Aufwand wiederhergestellt wird. Wenn Sie diese Commits jedoch verloren haben (z. B. weil Sie Ihr Repository in der Zwischenzeit nicht mehr gesammelt haben oder weil es sich um einen neuen Klon handelt), können Sie den Zweig immer wieder neu abstimmen. Der Schlüssel dazu ist der --onto-Schalter.

Angenommen, Sie hatten einen Themenzweig, der imaginativ als topic bezeichnet wurde, den Sie von master abgezweigt haben, als die Spitze von master der 0deadbeef-Befehl war. Irgendwann im Zweig topic haben Sie git rebase master ausgeführt. Jetzt möchten Sie das rückgängig machen. Hier ist wie:

git rebase --onto 0deadbeef master topic

Dadurch werden alle Commits für topic, die sich nicht für master befinden, übernommen und über 0deadbeef abgespielt.

Mit --onto können Sie Ihren Verlauf in beliebige Form umstellen.

Habe Spaß. :-)

79

Ich habe tatsächlich ein Backup-Tag in den Zweig gestellt, bevor ich eine nicht-triviale Operation durchführe (die meisten Rebases sind trivial, aber ich würde das tun, wenn es irgendwo komplex erscheint).

Dann ist das Wiederherstellen so einfach wie git reset --hard BACKUP.

64
Alex Gontmakher

Für den Fall Sie haben Ihren Zweig in das Remote-Repository verschoben (normalerweise ist es Origin) und dann haben Sie eine erfolgreiche Neueinstufung durchgeführt (ohne Zusammenführung) (git rebase --abort gibt "No rebase in progress" aus. Sie können einfach reset branch mit dem Befehl:

git reset --hard Origin/{branchName}

Beispiel:

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is ahead of 'Origin/{branchName}' by 135 commits.
  (use "git Push" to publish your local commits)

nothing to commit, working directory clean

$ ~/work/projects/{ProjectName} $ git reset --hard Origin/{branchName}
HEAD is now at 6df5719 "Commit message".

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is up-to-date with 'Origin/{branchName}.

nothing to commit, working directory clean
60
Maksym

Falls Sie die Rebase nicht abgeschlossen haben und in der Mitte, funktionieren die folgenden:

git rebase --abort
51
Alex

Die Verwendung von reflog hat bei mir nicht funktioniert.

Was für mich funktionierte, war ähnlich wie bei hier . Öffnen Sie die Datei in .git/logs/refs, die nach dem neu basierten Zweig benannt wurde, und suchen Sie nach der Zeile, die "rebase finsihed" enthält.

5fce6b51 88552c8f Kris Leech <[email protected]> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

Überprüfen Sie den zweiten Commit in der Zeile.

git checkout 88552c8f

Einmal bestätigt, dass dies meine verlorenen Änderungen enthielt, verzweigte ich mich und stieß einen erleichterten Seufzer aus.

git log
git checkout -b lost_changes
17
Kris

Denken Sie bei mehreren Commits daran, dass jedes Commit auf die gesamte Historie verweist, die zu diesem Commit geführt hat. Lesen Sie also in der Antwort von Charles "das alte Commit" als "das neueste der alten Commits". Wenn Sie auf diesen Commit zurücksetzen, wird der gesamte Verlauf, der zu diesem Commit geführt hat, wieder angezeigt. Dies sollte tun, was Sie wollen.

15
Greg Hewgill

Nach der Lösung von @Allan und @Zearin wünschte ich mir, ich könnte einfach einen Kommentar abgeben, aber ich habe nicht genug Ansehen, deshalb habe ich den folgenden Befehl verwendet:

Anstelle von git rebase -i --abort (beachten Sie die -i ), musste ich einfach git rebase --abort ( ohne die -i ) tun.

Bei gleichzeitiger Verwendung von -i und --abort zeigt Git eine Liste mit Verwendungsmöglichkeiten/Optionen an.

Mein bisheriger und aktueller Zweigstatus mit dieser Lösung ist also:

[email protected] /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort

[email protected] /my/project/environment (branch-123)
$
11
Matheus Felipe

Wenn Sie erfolgreich gegen einen Remote-Zweig basierten und nicht git rebase --abort können, können Sie immer noch einige Tricks ausführen, um Ihre Arbeit zu speichern, und haben keine erzwungenen Push-Vorgänge. Nehmen Sie an, Ihr aktueller Zweig, der versehentlich neu basiert wurde, heißt your-branch und verfolgt Origin/your-branch.

  • git branch -m your-branch-rebased # benennt den aktuellen Zweig um
  • git checkout Origin/your-branch # checkout zum neuesten Status, der Origin bekannt ist
  • git checkout -b your-branch
  • prüfen Sie git log your-branch-rebased, vergleichen Sie ihn mit git log your-branch und definieren Sie Commits, die in your-branch fehlen.
  • git cherry-pick COMMIT_HASH für jedes Commit in your-branch-rebased
  • Drücken Sie Ihre Änderungen. Bitte beachten Sie, dass zwei örtliche Zweigstellen mit remote/your-branch verknüpft sind, und Sie sollten nur your-branch drücken.
10

Nehmen wir an, ich baue Master an meinen Feature-Zweig zurück und erhalte 30 neue Commits, die etwas kaputt machen. Ich habe festgestellt, dass es oft am einfachsten ist, die schlechten Commits zu entfernen.

git rebase -i HEAD~31

Interaktive Erneuerung für die letzten 31 Commits (es tut nicht weh, wenn Sie zu viele auswählen).

Nehmen Sie einfach die Commits, die Sie entfernen möchten, und markieren Sie sie mit "d" anstelle von "pick". Jetzt werden die Commits gelöscht und die Rebase rückgängig gemacht (wenn Sie nur die Commits entfernen, die Sie gerade beim Rebasieren erhalten haben).

3
Hardev

Was ich normalerweise mache, ist git reset #commit_hash

bis zum letzten Commit, wo Rebase meiner Meinung nach keine Wirkung hatte.

dann git pull

Jetzt sollte Ihre Filiale genau mit dem Master übereinstimmen, und umbasierte Commits sollten nicht darin enthalten sein.

Jetzt kann man einfach die Commits für diesen Zweig auswählen.

1
mrigendra

Wenn Sie sich in einer Zweigstelle befinden, können Sie Folgendes verwenden:

git reset --hard @{1}

Es gibt nicht nur ein Referenzprotokoll für HEAD (von git reflog erhalten), es gibt auch für jeden Zweig ein Rückprotokoll (von git reflog <branch>). Wenn Sie sich also in master befinden, listet git reflog master alle Änderungen an diesem Zweig auf. Sie können auf diese Änderungen durch [email protected]{1}, [email protected]{2} usw. verweisen.

git rebase ändert normalerweise HEAD mehrmals, der aktuelle Zweig wird jedoch nur einmal aktualisiert.

@{1} ist einfach eine Verknüpfung für den aktuellen Zweig , also ist [email protected]{1} gleich, wenn Sie sich auf master befinden.

git reset --hard ORIG_HEAD funktioniert nicht, wenn Sie git reset während einer interaktiven rebase verwendet haben.

1
devconsole

Für Neulinge/alle, die Angst vor einem Hard-Reset haben, können Sie das Commit aus dem Reflog auschecken und es dann als neuen Zweig speichern.

git reflog

Suchen Sie den Commit, kurz bevor Sie mit dem Rebasing begonnen haben. Möglicherweise müssen Sie weiter nach unten scrollen, um sie zu finden (drücken Sie die Eingabetaste oder die Bild-Ab-Taste). Notieren Sie sich die HEAD Nummer und ersetzen Sie 57:

git checkout [email protected]{57}

Überprüfen Sie die Verzweigung/Commits, wenn es gut aussieht, erstellen Sie eine neue Verzweigung mit diesem HEAD:

git checkout -b new_branch_name
0
Andrew

git reset --hard Origin/{branchName}

ist die richtige Lösung, um alle Ihre durch Rebase vorgenommenen lokalen Änderungen zurückzusetzen.

0
Damodar P