wake-up-neo.net

Wie kann ich mehrere Git-Commits (bereits gepusht) auf ein veröffentlichtes Repository zurücksetzen?

Neu zu betrügen und schon vermasselt.

Ich habe einige Änderungen an einem Remote-Entwicklungscomputer vorgenommen und gepusht ... Ich muss eine ältere Version wiederherstellen, aber machen Sie den "schlechten Fortschritt" so weit, dass Sie an einem separaten Zweig arbeiten können.

Ich dachte, es so zu machen:

  1. Lokale Zweigstelle erstellen named: "getestet-thing"
  2. Lokales Repository zurücksetzen auf den Zustand, in dem es gearbeitet hat (hoffentlich sinnvolle Commits helfen);
  3. Push to Remote

  4. Tests am Testobjekt beenden 

  5. Merge "getestetes Ding" in dev
  6. Push to Remote

Zwischen den Schritten 3 und 5 können andere Entwickler Commit und Push ausführen, und ich befürchte, dass dies zu einer "Merge-Tragödie" führen kann.

UPDATE:

Das Hauptproblem liegt hier bei 2)

Hier zum Thema: "Arbeit in einen Zweig verzweigen" http://learn.github.com/p/undoing.html

Sie schlagen vor:

  1. $ git Branch Test
  2. $ git reset --hard a6b4c974

Auf diese Weise könnten andere Entwickler noch:

$ git commit (auf dem dev-Zweig)

und ich kann checkout to test und es bis zum merge Zeit ausarbeiten.

Trotz all Ihrer Möglichkeiten scheint dies ein netter Ansatz zu sein. Es ist jedoch nicht angegeben, ob dies möglich ist, nachdem wir gedrückt haben?

Bitte beachten Sie Folgendes: Da ich diese Änderungen vorgenommen habe und alles durcheinandergebrannt habe, bisher hat niemand mit dem Repository gearbeitet. Wenn ich also das Arbeitsverzeichnis zurücksetze, wird es niemand merken.

54
MEM

Das Problem

Es gibt eine Reihe von Arbeitsabläufen, die Sie verwenden können. Der wichtigste Punkt ist, die Geschichte in einem veröffentlichten Zweig nicht zu brechen, es sei denn, Sie haben mit jedem kommuniziert, der den Zweig konsumieren könnte und bereit sind, an jedem Klon eine Operation durchzuführen. Es ist am besten, dies nicht zu tun, wenn Sie es vermeiden können.

Lösungen für veröffentlichte Niederlassungen

Ihre umrissenen Schritte sind wertvoll. Wenn der Dev-Zweig sofort stabil sein soll, tun Sie es auf diese Weise. Sie haben eine Reihe von Tools für Debugging mit Git , die Ihnen helfen, den richtigen Verzweigungspunkt zu finden, und dann können Sie alle Commits zwischen Ihrem letzten stabilen Commit und HEAD zurücksetzen.

Entweder umkehren Sie die Commits einzeln in umgekehrter Reihenfolge oder verwenden Sie den <first_bad_commit>..<last_bad_commit>-Bereich. Hashes sind die einfachste Möglichkeit, den Festschreibungsbereich anzugeben, es gibt jedoch andere Notationen. Wenn Sie zum Beispiel 5 schlechte Commits gepusht haben, könnten Sie diese mit folgendem Befehl zurücksetzen:

# Revert a series using ancestor notation.
git revert --no-edit dev~5..dev

# Revert a series using commit hashes.
git revert --no-edit ffffffff..12345678

Dadurch werden umgekehrte Patches nacheinander auf Ihr Arbeitsverzeichnis angewendet und rückwärts zu Ihrem bekannt guten Commit verarbeitet. Mit dem Flag --no-edit werden die Änderungen an Ihrem Arbeitsverzeichnis automatisch übernommen, nachdem jeder umgekehrte Patch angewendet wurde.

Weitere Informationen finden Sie unter man 1 git-revert und man 7 gitrevisions, um die zurückzusetzenden Commits auf unterschiedliche Weise anzugeben.

Alternativ können Sie von Ihrem HEAD abzweigen, die Dinge wie gewünscht korrigieren und erneut zusammenführen. Ihr Build wird in der Zwischenzeit unterbrochen, dies kann jedoch in bestimmten Situationen sinnvoll sein.

Die Gefahrenzone

Wenn Sie absolut sicher sind, das seit Ihrem schlechten Push niemand mehr aus dem Repository gezogen hat, und wenn es sich bei der Fernbedienung um ein bare Repository handelt, können Sie natürlich eine Forward begehen.

git reset --hard <last_good_commit>
git Push --force

Dadurch bleibt der Reflog auf Ihrem System und dem vorgelagerten Host erhalten, aber Ihre fehlerhaften Commits werden aus der direkt zugänglichen Historie entfernt und werden bei Zügen nicht propagiert. Ihre alten Änderungen bleiben stehen, bis die Repositorys gelöscht werden, aber nur Git-Ninjas können die aus Versehen gemachten Commits sehen oder wiederherstellen.

105
Todd A. Jacobs

Wenn Sie bereits Dinge auf einen Remote-Server verschoben haben (und wenn andere Entwickler denselben Remote-Zweig bearbeiten), ist es wichtig, dass Sie den Verlauf nicht neu schreiben möchten

Nicht git reset --hard verwenden

Sie müssen die Änderungen rückgängig machen, andernfalls werden sie bei jedem Checkout, dessen entfernte Commits in der Historie enthalten sind, beim nächsten Push erneut zum Remote-Repository hinzugefügt. und jede andere Kasse zieht sie beim nächsten Zug ein.

Wenn Sie noch nicht Änderungen an einer Fernbedienung vorgenommen haben, können Sie dies verwenden

git reset --hard <hash>

Wenn Sie haben Änderungen gemacht haben, aber sicher sind, dass niemand sie gezogen hat, können Sie sie verwenden

git reset --hard
git Push -f

Wenn Sie haben Änderungen vorgenommen haben und jemand sie in die Kasse gezogen hat, können Sie dies immer noch tun, aber das andere Teammitglied/die Kasse müsste zusammenarbeiten:

(you) git reset --hard <hash>
(you) git Push -f

(them) git fetch
(them) git reset --hard Origin/branch

Aber im Allgemeinen wird das zum Chaos. Also umkehren:

Die zu entfernenden Commits sind die neuesten

Dies ist möglicherweise der häufigste Fall. Sie haben etwas getan - Sie haben sie herausgedrückt und dann erkannt, dass sie nicht existieren sollten.

Zuerst müssen Sie das Commit identifizieren, zu dem Sie zurückkehren möchten. Dies können Sie mit:

git log

suchen Sie einfach nach dem Commit vor Ihren Änderungen und notieren Sie den Commit-Hash. Sie können das Protokoll mit dem Flag -n auf die am meisten zurückgeschickten Commits beschränken: git log -n 5

Setzen Sie dann Ihren Zweig auf den Status zurück, den Ihre anderen Entwickler sehen sollen:

git revert  <hash of first borked commit>..HEAD

Der letzte Schritt besteht darin, eine eigene Zweigstelle zu erstellen, die Ihre zurückgesetzten Änderungen anwendet:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Arbeiten Sie weiter in my-new-branch, bis Sie fertig sind, und führen Sie ihn dann in Ihren Hauptentwicklungszweig ein.

Die zu entfernenden Commits werden mit anderen Commits vermischt

Wenn die Commits, die Sie zurücksetzen möchten, nicht alle zusammen sind, ist es wahrscheinlich am einfachsten, sie einzeln zurückzusetzen. Suchen Sie erneut mit git log die Commits, die Sie entfernen möchten, und dann:

git revert <hash>
git revert <another hash>
..

Erstellen Sie dann erneut Ihre Niederlassung, um Ihre Arbeit fortzusetzen:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Dann hack dich zurück und verschmelze, wenn du fertig bist.

Sie sollten mit einem Commit-Verlauf enden, der auf my-new-branch so aussieht.

2012-05-28 10:11 AD7six             o [my-new-branch] Revert "Revert "another mistake""
2012-05-28 10:11 AD7six             o Revert "Revert "committing a mistake""
2012-05-28 10:09 AD7six             o [master] Revert "committing a mistake"
2012-05-28 10:09 AD7six             o Revert "another mistake"
2012-05-28 10:08 AD7six             o another mistake
2012-05-28 10:08 AD7six             o committing a mistake
2012-05-28 10:05 Bob                I XYZ nearly works

Better way®

Da Sie jetzt die Gefahren mehrerer Entwickler kennen, die in derselben Branche arbeiten, sollten Sie die Zweige immer für Ihre Arbeit in Betracht ziehen. Alles, was bedeutet, ist in einem Zweig zu arbeiten, bis etwas fertig ist, und erst dann mit Ihrem Hauptzweig zusammenführen. Erwägen Sie auch die Verwendung von Tools wie git-flow , um die Erstellung von Zweigen konsistent zu automatisieren.

25
AD7six
git revert HEAD -m 1

In der obigen Codezeile. "Letztes Argument repräsentiert"

  • 1 - ein Commit wird zurückgesetzt. 2 - setzt letzte Commits zurück. n - gibt die letzten n Commits zurück

oder 

git reset --hard siriwjdd

0