Ich habe ein Git-Repository, das so aussieht:
A -> B -> C -> D -> HEAD
Ich möchte, dass der Kopf des Zweigs auf A zeigt, dh ich möchte, dass B, C, D und HEAD verschwinden, und ich möchte, dass der Kopf gleichbedeutend mit A ist.
Es hört sich so an, als könnte ich entweder versuchen, die Basis neu zu definieren (gilt nicht, da ich Änderungen dazwischen verschoben habe) oder zurücksetzen. Aber wie kann ich mehrere Commits zurücksetzen? Werde ich nacheinander zurücksetzen? Ist die Reihenfolge wichtig?
git
commit
git-revert
Rechnung
quelle
quelle
git push -f HEAD~4:master
(vorausgesetzt, der Remote-Zweig ist Master). Ja, Sie können jedes Commit so pushen.git revert
.Antworten:
Erweitern, was ich in einem Kommentar geschrieben habe
Die allgemeine Regel lautet, dass Sie den von Ihnen veröffentlichten Verlauf nicht neu schreiben (ändern) sollten, da möglicherweise jemand seine Arbeit darauf basiert hat. Wenn Sie den Verlauf neu schreiben (ändern), treten Probleme beim Zusammenführen der Änderungen und beim Aktualisieren auf.
Die Lösung besteht also darin, ein neues Commit zu erstellen , das Änderungen zurücksetzt , die Sie entfernen möchten. Sie können dies mit dem Befehl git revert tun .
Sie haben folgende Situation:
(Die Pfeile beziehen sich hier auf die Richtung des Zeigers: die "übergeordnete" Referenz bei Commits, die oberste Commit bei Verzweigungskopf (Verzweigungsreferenz) und der Name der Verzweigung bei HEAD-Referenz).
Was Sie erstellen müssen, ist Folgendes:
wobei "[(BCD) ^ - 1]" das Commit bedeutet, das Änderungen in den Commits B, C, D zurücksetzt. Die Mathematik sagt uns, dass (BCD) ^ - 1 = D ^ -1 C ^ -1 B ^ -1, also Sie können die erforderliche Situation mit den folgenden Befehlen erhalten:
Mögliche Lösung wäre, Kasse Inhalt der commit A, und verpflichten diesen Zustand:
Dann hätten Sie folgende Situation:
Das Festschreiben A 'hat den gleichen Inhalt wie Festschreiben A, ist jedoch ein anderes Festschreiben (Festschreibungsnachricht, Eltern, Festschreibungsdatum).
Die von Charles Bailey modifizierte Lösung von Jeff Ferland baut auf derselben Idee auf, verwendet jedoch Git-Reset :
quelle
git checkout -f A -- .
haben, werden diese nicht manuell gelöscht. Sie müssen dies manuell tun. Ich habe diese Strategie jetzt angewendet, danke Jakubgit checkout foo
Checkout- Zweigfoo
(Wechsel zum Zweig) oder Checkout- Datei foo (vom Index) bedeuten .--
wird verwendet, um zu disambiguieren, zBgit checkout -- foo
geht es immer um Datei.git revert --no-commit D C B
git revert
wurden nicht mehrere Commits akzeptiert. es ist ziemlich neu hinzugekommen.Sauberer Weg, den ich nützlich fand
Dieser Befehl setzt die letzten 3 Commits mit nur einem Commit zurück.
Schreibt auch die Geschichte nicht um.
quelle
git commit
von dort wird eigentlich das Commit machen.HEAD~3..
ist das gleiche wieHEAD~3..HEAD
Zu tun , so dass Sie nur die verwenden müssen revert Befehl unter Angabe des Bereichs von Commits wollen Sie kehrten erhalten.
Unter Berücksichtigung Ihres Beispiels müssten Sie dies tun (vorausgesetzt, Sie befinden sich in der Zweigstelle 'Master'):
Dadurch wird in Ihrem lokalen Bereich ein neues Commit mit dem inversen Commit von B, C und D erstellt (was bedeutet, dass die durch diese Commits eingeführten Änderungen rückgängig gemacht werden):
quelle
git revert --no-commit HEAD~2..
ist eine etwas idiomatischere Art, dies zu tun. Wenn Sie sich im Hauptzweig befinden, müssen Sie den Master nicht erneut angeben. Mit dieser--no-commit
Option kann git versuchen, alle Commits auf einmal zurückzusetzen, anstatt den Verlauf mit mehrerenrevert commit ...
Nachrichten zu verunreinigen (vorausgesetzt, Sie möchten dies).master~3
. H.--no-commit
(Sie erhalten also für jedes Zurücksetzen ein separates Commit) und dann alle zusammen in einer interaktiven Rebase zu quetschen. Die kombinierte Festschreibungsnachricht enthält alle SHAs, und Sie können sie mit Ihrem bevorzugten Festschreibungsnachrichten-Editor nach Belieben anordnen.Ähnlich wie bei Jakubs Antwort können Sie auf einfache Weise aufeinanderfolgende Commits zum Zurücksetzen auswählen.
quelle
B^..HEAD
, sonst ist B ausgeschlossen.git revert --no-commit B^..HEAD
odergit revert --no-commit A..HEAD
Das wird für alle gleichzeitig eine Rückkehr bedeuten. Geben Sie eine gute Commit-Nachricht.
quelle
HEAD
so aussehen möchte , möchteA
er wahrscheinlich, dass der Index übereinstimmt,git reset --soft D
was wahrscheinlich angemessener ist.git checkout A
danngit commit
oben hat bei mir nicht funktioniert, aber diese Antwort hat funktioniert.git reset --mixed D
erforderlich? Speziell warumreset
? Liegt es daran, dass HEAD ohne Zurücksetzen auf D auf A zeigt und B, C und D "baumelt" und Müll sammelt - was er nicht will? Aber warum dann--mixed
? Sie haben bereits geantwortet: "--soft
Zurücksetzen verschiebt den Index nicht ..." Wenn Sie also den Index verschieben, bedeutet dies, dass der Index die Änderungen von D enthält, während das Arbeitsverzeichnis die Änderungen von A enthält - auf diese Weise eingit status
odergit diff
(das Index [D] mit vergleicht Arbeitsverzeichnis [A]) zeigt den Stoff; Dieser Benutzer wechselt von D zurück zu A?Stellen Sie zunächst sicher, dass Ihre Arbeitskopie nicht geändert wird. Dann:
und dann einfach festschreiben. Vergessen Sie nicht zu dokumentieren, was der Grund für die Rücknahme ist.
quelle
error: cannot apply binary patch to 'some/image.png' without full index line error: some/image.png: patch does not apply
git diff --binary HEAD commit_sha_you_want_to_revert_to | git apply
git revert A..Z
Sie verwenden, erhalten Sieerror: commit X is a merge but no -m option was given.
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 lautet: "Ich möchte, dass der Kopf des Zweigs auf A zeigt, dh ich möchte, dass B, C, D und HEAD verschwinden und dass der Kopf gleichbedeutend mit A ist."
Ich habe viel gelernt, als ich Jakubs Post gelesen habe, aber ein Typ in der Firma (mit Zugriff auf unsere "Test" -Zweige ohne Pull-Request) hat wie 5 schlechte Commits versucht, einen Fehler zu beheben, den er vor 5 Commits gemacht hat. Nicht nur das, sondern auch ein oder zwei Pull-Anfragen wurden akzeptiert, die jetzt schlecht waren. Also vergiss es, ich habe das letzte gute Commit gefunden (abc1234) und nur das Basisskript ausgeführt:
Ich sagte den anderen 5 Jungs, die in diesem Repo arbeiten, dass sie ihre Änderungen in den letzten Stunden und Wipe / Re-Branch von den letzten Tests besser notieren sollten. Das Ende der Geschichte.
quelle
git push --force-with-lease
, die Geschichte nur dann neu zu schreiben, wenn sich nach oder innerhalb des Bereichs der zu verdampfenden Commits niemand anderes für den Zweig verpflichtet hat. Wenn andere Personen den Zweig verwendet haben, sollte sein Verlauf niemals neu geschrieben werden, und das Festschreiben sollte einfach sichtbar rückgängig gemacht werden.Dies ist eine Erweiterung einer der in Jakubs Antwort enthaltenen Lösungen
Ich war mit einer Situation konfrontiert, in der die Commits, die ich zurücksetzen musste, etwas komplex waren. Einige der Commits waren Merge-Commits, und ich musste vermeiden, den Verlauf neu zu schreiben. Ich konnte eine Reihe von
git revert
Befehlen nicht verwenden, da ich schließlich auf Konflikte zwischen den hinzugefügten Umkehrungsänderungen stieß. Am Ende habe ich die folgenden Schritte ausgeführt.Überprüfen Sie zunächst den Inhalt des Ziel-Commits, während Sie HEAD an der Spitze des Zweigs belassen:
(Das - stellt sicher, dass
<target-commit>
es als Commit und nicht als Datei interpretiert wird. Das. Verweist auf das aktuelle Verzeichnis.)Stellen Sie dann fest, welche Dateien in den zurückgesetzten Commits hinzugefügt wurden und daher gelöscht werden müssen:
Dateien, die hinzugefügt wurden, sollten am Anfang der Zeile mit einem "A" angezeigt werden, und es sollten keine weiteren Unterschiede bestehen. Wenn nun Dateien entfernt werden müssen, stellen Sie diese Dateien zum Entfernen bereit:
Zum Schluss die Umkehrung festschreiben:
Stellen Sie auf Wunsch sicher, dass wir wieder im gewünschten Zustand sind:
Es sollte keine Unterschiede geben.
quelle
git
nur mit der Spitze des Zweiges KOPFEN können ?Die einfache Möglichkeit, eine Gruppe von Commits im freigegebenen Repository (die von Benutzern verwendet wird und Sie den Verlauf beibehalten möchten) zurückzusetzen, besteht in der Verwendung
git revert
in Verbindung mit gitrev-list
. Der letztere liefert Ihnen eine Liste der Commits, der erstere führt das Zurücksetzen selbst durch.Dafür gibt es zwei Möglichkeiten. Wenn Sie mehrere Commits in einem einzigen Commit zurücksetzen möchten, verwenden Sie:
Dadurch wird eine Gruppe von Commits zurückgesetzt, die Sie benötigen. Wenn Sie jedoch alle Änderungen in Ihrem Arbeitsbaum belassen, sollten Sie sie wie gewohnt festschreiben.
Eine andere Option besteht darin, ein einziges Commit pro rückgängig gemachter Änderung durchzuführen:
Zum Beispiel, wenn Sie einen Commit-Baum wie haben
Um die Änderungen von eee auf bbb zurückzusetzen , führen Sie aus
quelle
Keiner von diesen hat für mich funktioniert, also musste ich drei Commits zurücksetzen (die letzten drei Commits), also tat ich:
Lief wie am Schnürchen :)
quelle
Meiner Meinung nach könnte ein sehr einfacher und sauberer Weg sein:
gehe zurück zu A.
Zeigen Sie mit dem Kopf des Masters auf den aktuellen Status
speichern
quelle
git checkout master; git reset --hard A
? Oder wenn nicht, könnten Sie etwas mehr darüber erklären, was dies bewirkt?Wenn Sie die Commits eines Features vorübergehend zurücksetzen möchten, können Sie die folgenden Befehle verwenden.
So funktioniert es
git log --pretty = oneline | grep 'feature_name' | cut -d '' -f1 | xargs -n1 git revert --no-edit
quelle