1647 Stimmen

Wie kann man mehrere Git-Commits rückgängig machen?

Ich habe ein Git-Repository, das wie folgt aussieht:

A <- B <- C <- D <- HEAD

Ich möchte, dass der Kopf der Verzweigung auf A zeigt, d.h. ich möchte, dass B, C, D und HEAD verschwinden, und ich möchte, dass head ein Synonym für A ist.

Es klingt so, als ob ich entweder versuchen könnte, neu zu basen (trifft nicht zu, da ich zwischendurch Änderungen vorgenommen habe) oder zu revertieren. Aber wie kann ich mehrere Übertragungen rückgängig machen? Mache ich einen nach dem anderen rückgängig? Ist die Reihenfolge wichtig?

95voto

Suamere Punkte 4914

Ich bin so frustriert, dass diese Frage nicht einfach beantwortet werden kann. Jede andere Frage bezieht sich darauf, wie man richtig zurückkehrt und die Geschichte bewahrt. Diese Frage sagt "Ich möchte, dass der Kopf der Verzweigung auf A zeigt, d.h. ich möchte, dass B, C, D und HEAD auf verschwinden und ich möchte, dass Kopf ein Synonym für A ist."

git checkout <branch_name>
git reset --hard <commit Hash for A>
git push -f

Ich habe viel gelernt, indem ich Jakubs Beitrag gelesen habe, aber irgendein Kerl in der Firma (mit Zugang zu unserem "Test"-Zweig ohne Pull-Request) hat etwa 5 schlechte Commits gepusht und versucht, einen Fehler, den er vor 5 Commits gemacht hat, zu korrigieren und zu korrigieren und zu korrigieren. Nicht nur das, es wurden auch ein oder zwei Pull-Requests akzeptiert, die nun schlecht waren. Also vergiss es, ich fand den letzten guten Commit (abc1234) und führte einfach das Basisskript aus:

git checkout testing
git reset --hard abc1234
git push -f

Ich habe den anderen 5 Leuten, die an diesem Repo arbeiten, gesagt, dass sie besser ihre Änderungen der letzten Stunden notieren und von den letzten Tests löschen/neu verzweigen sollen. Ende der Geschichte.

76voto

mateusz.fiolka Punkte 2914

Stellen Sie zunächst sicher, dass Ihre Arbeitskopie nicht verändert wird. Dann:

git diff --binary HEAD commit_sha_you_want_to_revert_to | git apply

und dann einfach zusagen. Vergessen Sie nicht zu dokumentieren, was der Grund für den Revert ist.

36voto

meh Punkte 1913

Git verwenden Restore

Sie können auch die restore Befehl:

A <- B <- C <- D <- HEAD

Nehmen wir an, Sie wollen HEAD genau so aussehen wie A . Stellen Sie sicher, dass Sie die neuesten master . Dann schneiden Sie einen neuen Zweig.

git switch -c feature/flux-capacitor  # synonymous with checkout -b
git restore --source <A's commit hash> .
git add .
git commit
git push

El restore Befehl ändert alles ( . ) zu dem, was sie zum Zeitpunkt der --source verpflichten. Dann übertragen Sie es in Ihren lokalen Zweig und schieben es in den Ursprung. Sie können dann einen PR dafür öffnen.

Dies hat den Vorteil, dass die Geschichte, auf die sich andere möglicherweise gestützt haben, nicht verändert wird. Außerdem bleibt so eine nützliche Historie für die Zukunft erhalten.

Dokumente: Git-Wiederherstellung

20voto

Warren Dew Punkte 8502

Dies ist eine Erweiterung einer der Lösungen, die in Jakubs Antwort enthalten sind

Ich war mit einer Situation konfrontiert, in der die Commits, die ich zurücksetzen musste, ziemlich komplex waren, wobei mehrere der Commits Merge-Commits waren, und ich musste vermeiden, die Geschichte neu zu schreiben. Ich war nicht in der Lage, eine Reihe von git revert Befehle, weil ich irgendwann auf Konflikte zwischen den hinzugefügten Rückgängigmachungsänderungen gestoßen bin. Am Ende habe ich die folgenden Schritte verwendet.

Checken Sie zunächst den Inhalt der Ziel-Commit aus, während Sie HEAD an der Spitze des Zweigs belassen:

$ git checkout -f <target-commit> -- .

(Die -- stellt sicher <target-commit> wird als Commit und nicht als Datei interpretiert; das . bezieht sich auf das aktuelle Verzeichnis).

Bestimmen Sie dann, welche Dateien in den zurückgenommenen Commits hinzugefügt wurden und daher gelöscht werden müssen:

$ git diff --name-status --cached <target-commit>

Die hinzugefügten Dateien sollten mit einem "A" am Anfang der Zeile angezeigt werden, und es sollte keine weiteren Unterschiede geben. Wenn nun Dateien entfernt werden müssen, markieren Sie diese Dateien zum Entfernen:

$ git rm <filespec>[ <filespec> ...]

Übertragen Sie schließlich die Umkehrung:

$ git commit -m 'revert to <target-commit>'

Falls gewünscht, stellen Sie sicher, dass der gewünschte Zustand wiederhergestellt ist:

$git diff <target-commit> <current-commit>

Es sollte keine Unterschiede geben.

9voto

Ruslan Kabalin Punkte 5900

Der einfachste Weg, eine Gruppe von Commits in einem gemeinsam genutzten Repository (das von anderen genutzt wird und dessen Historie erhalten bleiben soll) zurückzunehmen, ist die Verwendung von git revert in Verbindung mit Git rev-list . Letzteres liefert Ihnen eine Liste der Commits, ersteres führt den Revert selbst durch.

Es gibt zwei Möglichkeiten, dies zu tun. Wenn Sie mehrere Commits in einem einzigen Commit rückgängig machen wollen, verwenden Sie:

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-commit $i; done

Dies wird eine Gruppe von Commits, die Sie benötigen, zurücknehmen, aber alle Änderungen in Ihrem Arbeitsbaum belassen, Sie sollten sie danach wie gewohnt committen.

Eine andere Möglichkeit ist eine einzelne Übergabe pro rückgängig gemachter Änderung:

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-edit -s $i; done

Wenn Sie zum Beispiel einen Commit-Baum haben wie

 o---o---o---o---o---o--->    
fff eee ddd ccc bbb aaa

um die Änderungen von eee a bbb , laufen

for i in `git rev-list eee^..bbb`; do git revert --no-edit -s $i; done

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X