Remote auf ein bestimmtes Commit zurücksetzen

709

Ich möchte alle nach dem Festschreiben vorgenommenen Änderungen verwerfen <commit-hash>. So tat ich:

git reset --hard <commit-hash>

Jetzt möchte ich dasselbe mit meiner Fernbedienung machen. Wie kann ich das machen? Ich habe danach einige Commits (und Pushs) durchgeführt <commit-hash>und möchte sie nur alle verwerfen. Ist nur etwas furchtbar schief gelaufen und ich möchte es nicht schlimmer machen als es schon ist. ; (

Ich möchte im Grunde meine zurückzuspulen origin/masterzu<commit-hash>

nacho4d
quelle
3
Sind Sie sicher, dass Sie origin/masternicht von anderen Benutzern gezogen und gedrückt wurden? Das Ändern des Verlaufs eines öffentlichen (dh nicht lokalen) Repositorys sollten Sie jederzeit vermeiden.
Vindia
Mögliches Duplikat von Wie werden mehrere Git-Commits zurückgesetzt?
Michael Freidgeim

Antworten:

1251

Angenommen, Ihre Niederlassung wird mastersowohl hier als auch remote aufgerufen , und Ihre Fernbedienung wird aufgerufen origin, könnten Sie Folgendes tun:

 git reset --hard <commit-hash>
 git push -f origin master

Sie sollten dies jedoch vermeiden, wenn jemand anderes mit Ihrem Remote-Repository arbeitet und Ihre Änderungen abgerufen hat. In diesem Fall wäre es besser, zufällt Commits , dass Sie nicht wollen, dann ganz normal drücken.

Update: Sie haben unten erklärt, dass andere Personen die von Ihnen vorgenommenen Änderungen übernommen haben. Daher ist es besser, ein neues Commit zu erstellen, das alle diese Änderungen zurücksetzt . In dieser Antwort von Jakub Narębski finden Sie eine schöne Erklärung Ihrer Möglichkeiten, dies zu tun . Welche Methode am bequemsten ist, hängt davon ab, wie viele Commits Sie zurücksetzen möchten und welche Methode für Sie am sinnvollsten ist.

Da aus Ihrer Frage hervorgeht, dass Sie git reset --hardIhren masterZweig bereits zurückgesetzt haben , müssen Sie möglicherweise zunächst verwenden git reset --hard ORIG_HEAD, um Ihren Zweig wieder an den vorherigen Ort zu verschieben. ( Stellen Sie wie immer git reset --hardsicher, dass dies git statussauber ist, dass Sie sich auf dem richtigen Zweig befinden und dass Sie sich git reflogals Werkzeug zur Wiederherstellung scheinbar verlorener Commits bewusst sind .) Sie sollten auch überprüfen, ob ORIG_HEADauf das richtige Commit verweist, mit git show ORIG_HEAD.

Fehlerbehebung:

Wenn Sie eine Nachricht wie " ! [Remote abgelehnt] a60f7d85 -> master (Hook vor dem Empfang abgelehnt) " erhalten

Dann müssen Sie das Umschreiben des Zweigverlaufs für den jeweiligen Zweig zulassen. In BitBucket heißt es beispielsweise "Das Umschreiben des Zweigverlaufs ist nicht zulässig". Es gibt ein Kontrollkästchen mit dem Namen, Allow rewriting branch historydas Sie aktivieren müssen.

Mark Longair
quelle
21
Gefahrengefahr: Bei diesem Zurücksetzen wird davon ausgegangen, dass der entsprechende ( Tracking- ) Zweig derzeit ausgecheckt ist und keine nicht festgeschriebenen Änderungen vorhanden sind, die Sie beibehalten möchten. Verwenden Sie git update-refanstelle vonreset --hard ; es wird Ihnen ermöglichen, dasselbe zu tun, ohne einen funktionierenden Baum /
ausgecheckten
3
Aha. Es wurde von anderen vorangetrieben und verändert. Also sollte ich verwenden, revert aber sagen wir, ich möchte die letzten 4 Commits zurücksetzen, also sollte ich es tun git revert comit1; git push; git revert comit2; git push; ...oder einfach git revert commit4; git push?
Nacho4D
1
@ nacho4d: Sie müssen nicht nach jedem Zurücksetzen pushen - in dieser Antwort von Jakub Narębski finden Sie eine schöne Beschreibung, was zu tun ist . Sie müssen jedes Commit rückwärts git revert commit4zurücksetzen. Wenn Sie dies tun, wird ein neues Commit erstellt, das nur die Änderungen rückgängig macht, die in eingeführt wurden commit4. Wie die Antwort, auf die ich verwiesen habe, zeigt, können Sie diese in einem einzigen Commit zusammenfassen.
Mark Longair
1
@Mark Ich habe bereits ausgeführt, git reset --hardaber ich habe mein lokales gelöscht und wieder vom Ursprung gezogen, damit ich es tun kann. git revert ...Mein Zweifel ist jetzt: Muss ich jedes Commit und Push (eins nach dem anderen) zurücksetzen oder einfach das erste Commit nach dem zurücksetzen nur richtig begehen?
Nacho4d
1
@sehe: Es ist schwierig zu verwenden, da Sie den vollständigen Ref-Namen verwenden müssen. Daher ist es für Benutzer einfach, ihr .gitVerzeichnis mit Refs zu verunreinigen , die sie nicht erstellen wollten. Ich habe zu Unrecht gesagt, dass es keine Sicherheitsüberprüfungen gibt. Die Klassifizierung in die Befehle "Sanitär" und "Porzellan" finden Sie auf der Git-Manpage .
Mark Longair
123

Verwenden Sie die anderen Antworten, wenn es Ihnen nichts ausmacht, lokale Änderungen zu verlieren. Diese Methode kann Ihre Fernbedienung immer noch zerstören, wenn Sie den falschen Commit-Hash auswählen, zu dem Sie zurückkehren möchten.

Wenn Sie nur die Remote-Übereinstimmung zu einem Commit machen möchten, das sich in Ihrem lokalen Repo befindet:

  1. Sie nicht jedes Zurücksetzen tun.
  2. Verwenden git logSie diese Option , um das Commit zu finden, bei dem sich die Fernbedienung befinden soll. git log -pum Änderungen zu sehen oder git log --graph --all --oneline --decorateum einen kompakten Baum zu sehen.
  3. Kopieren Sie den Hash oder das Tag des Commits oder den Namen seines Zweigs, wenn es der Tipp ist.
  4. Führen Sie einen Befehl wie folgt aus:

    git push --force <remote> <commit-ish>:<the remote branch>
    

    z.B

    git push --force origin 606fdfaa33af1844c86f4267a136d4666e576cdc:master
    

    oder

    git push --force staging v2.4.0b2:releases
    

Ich verwende den praktischen Alias ​​( git go) zum Anzeigen des Verlaufs wie in Schritt 2, der wie folgt hinzugefügt werden kann:

    git config --global alias.go 'log --graph --all --decorate --oneline'`
Walf
quelle
3
Die Grafik war ein sehr schöner Tipp. Ich habe gerade -5 hinzugefügt, um nur die letzten n Commits zu erhalten. Es war ein riesiger Baum. Auch das Vermeiden des Zurücksetzens ist genau das, wonach ich gesucht habe. Großartig
AlexanderD
@AlexanderD Sie können den Alias ​​auch zu Git anstatt zu Ihrer Shell hinzufügen, sodass er überall funktioniert. Git versteht diese Aliase und Tab-Vervollständigungen aus dem vollständigen Befehl, sodass Sie Argumente hinzufügen können. git config --global alias.graph 'log --graph --all --decorate --oneline'ist weniger chaotisch und Sie können es immer noch einschränken, zB:git graph -5
Walf
Dies ist perfekt. Ich habe meinen Einheimischen immer durcheinander gebracht. Dies war genau das, was ich brauchte, nachdem ich versehentlich meine Inszenierung zum Leben erweckt hatte :( Danke!
Jake
1
Geben Sie unter Windows ein, um qdas Git-Protokoll zu beenden. 2 Minuten werde ich nie zurückkommen.
dst3p
1
@ dst3p Das ist auf jeder Plattform, Kumpel. Das Pager-Programm ist normalerweise lessund qist der normale Weg, um es zu beenden. Git Bash ist wie ein * nix-Terminal.
Walf
63

Ich habe ein Problem wie das Ihre mit folgenden Befehlen gelöst:

git reset --hard <commit-hash> 
git push -f <remote> <local branch>:<remote branch> 
Ibrohim Ermatov
quelle
13

In GitLab müssen Sie möglicherweise Ihren Zweig auf ungeschützt setzen, bevor Sie dies tun. Sie können dies unter [Repo]> Einstellungen> Repository> Geschützte Zweige tun. Dann funktioniert die Methode aus Marks Antwort.

git reset --hard <commit-hash>
git push -f origin master
dudasaus
quelle
10

Wenn Sie eine frühere Version der Datei möchten, würde ich die Verwendung von git checkout empfehlen.

git checkout <commit-hash>

Wenn Sie dies tun, werden Sie in der Zeit zurückgeschickt. Dies hat keinen Einfluss auf den aktuellen Status Ihres Projekts. Sie können zur Hauptlinie Git Checkout Mainline gelangen

Wenn Sie dem Argument jedoch eine Datei hinzufügen, wird diese Datei von einer früheren Zeit zu Ihrer aktuellen Projektzeit zurückgesetzt, dh Ihr aktuelles Projekt wird geändert und muss festgeschrieben werden.

git checkout <commit-hash> -- file_name
git add .
git commit -m 'file brought from previous time'
git push

Dies hat den Vorteil, dass der Verlauf nicht gelöscht wird und bestimmte Codeänderungen auch nicht zurückgesetzt werden (git revert).

Weitere Informationen finden Sie hier https://www.atlassian.com/git/tutorials/undoing-changes#git-checkout

Priya Khokher
quelle
Dies ist eine ausgezeichnete Antwort: Es funktioniert, Punkt und ist sehr sicher; Wenn Sie es vermasseln, ist es einfach, zurück zu gehen.
Bob
8

Meine zwei Cent zu den vorherigen Antworten: wenn

git push --force <remote> <the-hash>:<the remote branch>

funktioniert immer noch nicht, möglicherweise möchten Sie <your-remote-repo>.git/configden Empfangsbereich der Datei bearbeiten :

[receive]
  #denyNonFastforwards = true
  denyNonFastforwards = false
Badbishop
quelle
Es ist hilfreich zu wissen, wie eine Fernbedienung so konfiguriert wird, dass Pushs ohne schnellen Vorlauf möglich sind, da die meisten Antworten von einem Remote-Dienst wie Github oder Bitbucket ausgehen.
strongbutgood
2

Wenn es sich bei Ihrer Niederlassung nicht um Entwicklung oder Produktion handelt, können Sie dies am einfachsten auf ein bestimmtes Commit vor Ort zurücksetzen und von dort aus eine neue Niederlassung erstellen. Sie können verwenden:

Git Checkout 000000

(wobei 000000 die Festschreibungs-ID ist, zu der Sie gehen möchten) in Ihrem problematischen Zweig und erstellen Sie dann einfach einen neuen Zweig:

git remote add [name_of_your_remote]

Dann können Sie eine neue PR erstellen und alles wird gut funktionieren!

Gerardo Suarez
quelle
1

Machen Sie eine Sache, holen Sie sich die SHA-Nr. wie 87c9808 und dann

  1. Bewegen Sie sich, das ist Ihr Kopf zum angegebenen Commit (indem Sie git reset ausführen --hard 89cef43 // Geben Sie hier Ihre Nummer an)
  2. Nehmen Sie als Nächstes einige Änderungen in einer zufälligen Datei vor, damit der Git Sie auffordert, diese lokal und dann remote festzuschreiben. Daher müssen Sie jetzt Folgendes tun. nach dem Anwenden von change git commit -a -m "Test-Commit"
  3. Drücken Sie nun das folgende Commit (falls dies lokal festgeschrieben wurde) von git push origin master
  4. Nun, was Git von dir verlangen wird, ist das

Fehler: Einige Refs konnten nicht an ' https://github.com/YOURREPOSITORY/AndroidExperiments.git ' gesendet werden. Hinweis: Aktualisierungen wurden abgelehnt, da sich die Spitze Ihres aktuellen Zweigs hinter dem Hinweis befindet: dem Remote-Gegenstück. Integrieren Sie die Remote-Änderungen (z. B. Hinweis: 'git pull ...'), bevor Sie erneut drücken. **

  1. So können Sie jetzt tun

git push --force origin master

  1. Und so hoffe ich, dass es funktioniert :)
Siddharth Choudhary
quelle
1

Quellenbaum: Remote auf ein bestimmtes Commit zurücksetzen

  1. Wenn Sie ein schlechtes Commit auf Ihre Fernbedienung (origin / feature / 1337_MyAwesomeFeature) übertragen haben, wie im folgenden Bild dargestellt

Gehen Sie zu Fernbedienungen

  1. Gehen Sie zu Fernbedienungen> Ursprung> Funktion> 1337_MyAwesomeFeature
  2. Klicken Sie mit der rechten Maustaste und wählen Sie "Ursprung / Feature / 1337_MyAwesomeFeature löschen" (oder ändern Sie den Namen, wenn Sie eine Sicherung wünschen, und überspringen Sie Schritt 4.)
  3. Klicken Sie auf "Löschen erzwingen" und "OK".

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

  1. Wählen Sie Ihr älteres Commit aus und wählen Sie "Aktuellen Zweig auf dieses Commit zurücksetzen".
  2. Wählen Sie den gewünschten Modus (Schwer, wenn Sie Ihre letzten Änderungen nicht möchten) und "OK".

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

  1. Verschieben Sie dieses Commit auf ein neues origin / feature / 1337_MyAwesomeFeature Geben Sie hier die Bildbeschreibung ein

  2. Ihr lokaler Feature-Zweig und Ihr Remote-Feature-Zweig befinden sich jetzt im vorherigen Commit (Ihrer Wahl) Geben Sie hier die Bildbeschreibung ein

Joel Wiklund
quelle