single - git undo commit




Verschieben Sie die letzten Commits mit Git in einen neuen Zweig (8)

Im Algemeinen...

Die von Sykora offenbarte Methode ist in diesem Fall die beste Option. Aber manchmal ist es nicht die einfachste und keine allgemeine Methode. Für eine allgemeine Methode verwenden Sie git cherry-pick :

Um das zu erreichen, was OP will, ist es ein zweistufiger Prozess:

Schritt 1 - newbranch Sie, welche Commits von einem Master in einer newbranch

Ausführen

git checkout master
git log

newbranch Sie sich die Hashwerte von (etwa 3) Commits, die Sie für die newbranch . Hier werde ich verwenden:
C Commit: 9aa1233
D-Commit: 453ac3d
E-Commit: 612ecb3

Hinweis: Sie können die ersten sieben Zeichen oder den gesamten Commit-Hash verwenden

Schritt 2 - Legen Sie sie auf die newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

ODER (in Git 1.7.2+ Bereiche verwenden)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

git cherry-pick wendet diese drei Verpflichtungen an die neue Niederlassung an.

Ich möchte die letzten verschiedenen Commits, die ich zu einem Master gemacht habe, in einen neuen Zweig verschieben und den Master vor dem Commit wieder aufnehmen. Leider ist mein Git-Fu noch nicht stark genug.

Dh wie kann ich davon gehen?

master A - B - C - D - E

zu diesem

newbranch     C - D - E
             /
master A - B 

Viel einfachere Lösung mit Git Stash

Ob:

  • Ihr Hauptzweck besteht darin, master , und
  • Sie möchten Änderungen beibehalten, kümmern sich aber nicht besonders um die einzelnen Commits und
  • Sie haben noch nicht gedrückt, und
  • Sie möchten, dass dies mit temporären Ästen und anderen Kopfschmerzen leicht und nicht kompliziert ist

Dann ist das Folgende viel einfacher (beginnend mit einem master , der drei fehlerhafte Commits hat):

git reset HEAD~3
git stash
git checkout newbranch
git stash pop

Was das macht, nach Zeilennummer

  1. Macht die letzten drei Commits (und ihre Nachrichten) für den master rückgängig, belässt jedoch alle Arbeitsdateien
  2. Verwirft alle Änderungen der Arbeitsdatei und macht den master Arbeitsbaum mit dem Status HEAD ~ 3 gleich
  3. Wechselt zu einer bestehenden Zweigstelle
  4. Wendet die zwischengespeicherten Änderungen in Ihrem Arbeitsverzeichnis an und löscht den Stash

Sie können git add und git commit jetzt wie git add . Alle neuen Commits werden in newbranch hinzugefügt.

Was macht das nicht?

  • Es hinterlässt keine zufälligen temporären Äste, die Ihren Baum stören
  • Die fehlerhaften Commits und Commit-Nachrichten bleiben dabei nicht erhalten. Daher müssen Sie dem neuen Commit eine neue Commit-Nachricht hinzufügen

Tore

Das OP erklärte, es sei das Ziel, "den Meister zurückzubringen, bevor diese Commits gemacht wurden", ohne Änderungen zu verlieren, und diese Lösung tut dies.

Ich mache dies mindestens einmal in der Woche, wenn ich versehentlich neue Commits mache, um sie zu master anstatt sich zu develop . Normalerweise habe ich nur ein Commit für das Rollback. In diesem Fall ist die Verwendung von git reset HEAD^ in Zeile 1 eine einfachere Methode, um nur ein Commit zurückzusetzen.

Tun Sie dies nicht, wenn Sie die Änderungen des Masters in den Upstream verschoben haben

Möglicherweise hat jemand anderes diese Änderungen vorgenommen. Wenn Sie nur Ihren lokalen Master umschreiben, hat dies keine Auswirkungen, wenn er in den Upstream-Modus verschoben wird. Wenn Sie jedoch einen neu geschriebenen Verlauf an die Mitarbeiter weiterleiten, kann dies zu Problemen führen.


Umzug in eine neue Niederlassung

WARNUNG: Diese Methode funktioniert, weil Sie mit dem ersten Befehl einen neuen Zweig erstellen: git branch newbranch . Wenn Sie Commits in einen vorhandenen Zweig verschieben möchten, müssen Sie Ihre Änderungen im vorhandenen Zweig zusammenführen, bevor Sie git reset --hard HEAD~3 ausführen (siehe Zu einem vorhandenen Zweig git reset --hard HEAD~3 ). Wenn Sie Ihre Änderungen nicht zuerst zusammenführen, gehen sie verloren.

Wenn keine anderen Umstände vorliegen, kann dies leicht durch Verzweigen und Zurückrollen durchgeführt werden.

# Note: Any changes not committed will be lost.
git branch newbranch      # Create a new branch, saving the desired commits
git reset --hard HEAD~3   # Move master back by 3 commits (GONE from master)
git checkout newbranch    # Go to the new branch that still has the desired commits

Aber stellen Sie sicher, wie viele Verpflichtungen Sie zurückgeben. Alternativ können Sie anstelle von HEAD~3 einfach den Hash des Commits (oder der Referenz wie Origin / Master ) angeben, zu dem Sie auf dem Master- Zweig (/ current) zurückkehren möchten, z.

git reset --hard a1b2c3d4

* 1 Sie werden nur Commits aus dem Master-Zweig "verlieren", aber keine Sorge, Sie haben diese Commits in einer neuen Niederlassung!

WARNUNG: Wenn Sie mit Git ab Version 2.0 den neuen Zweig git rebase neu auf den ursprünglichen Zweig ( master ) setzen, benötigen Sie möglicherweise eine explizite Option --no-fork-point während der Rebase, damit die übertragenen Commits nicht verloren gehen. Wenn branch.autosetuprebase always gesetzt ist, wird dies wahrscheinlicher. Einzelheiten finden Sie in der Antwort von John Mellor .

Umzug in eine bestehende Niederlassung

Wenn Sie Ihre Commits in einen vorhandenen Zweig verschieben möchten, sieht das folgendermaßen aus:

git checkout existingbranch
git merge master
git checkout master
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.
git checkout existingbranch

1) Erstellen Sie einen neuen Zweig, der alle Ihre Änderungen in new_branch verschiebt.

git checkout -b new_branch

2) Gehen Sie dann zum alten Zweig zurück.

git checkout master

3) Gib git rebase

git rebase -i <short-hash-of-B-commit>

4) Der geöffnete Editor enthält dann die letzten 3 Commit-Informationen.

...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...

5) Ändern Sie die pick , drop alle drei Commits abzulegen. Dann speichern und schließen Sie den Editor.

...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...

6) Nun werden die letzten 3 Commits aus dem aktuellen Zweig ( master ) entfernt. Drücken Sie nun die Verzweigung mit + vor dem Namen der Verzweigung.

git push origin +master

Eine weitere Möglichkeit, dies zu tun, indem nur zwei Befehle verwendet werden. Behält auch Ihren aktuellen Arbeitsbaum bei.

git checkout -b newbranch # switch to a new branch
git branch -f master HEAD~3 # make master point to some older commit

Alte Version - bevor ich etwas über git branch -f gelernt habe

git checkout -b newbranch # switch to a new branch
git push . +HEAD~3:master # make master point to some older commit 

In der Lage zu push . ist ein schöner Trick zu wissen.


Für diejenigen, die sich fragen, warum es funktioniert (wie ich zuerst war):

Sie möchten zu C zurückkehren und D und E in den neuen Zweig verschieben. So sieht es zunächst aus:

A-B-C-D-E (HEAD)
        ↑
      master

Nach git branch newBranch :

    newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

Nach git reset --hard HEAD~2 :

    newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

Da ein Zweig nur ein Zeiger ist, zeigte der Master auf das letzte Commit. Bei der Erstellung von newBranch haben Sie einfach einen neuen Zeiger auf den letzten Commit erstellt. Dann haben Sie mit git reset den Masterzeiger um zwei Commits nach hinten verschoben. Da Sie newBranch jedoch nicht verschoben haben , deutet dies immer noch auf das Commit hin, das ursprünglich ausgeführt wurde.


Sie können dies tun, ist nur 3 einfachen Schritt, den ich verwendet habe.

1) Erstellen Sie einen neuen Zweig, in dem Sie Ihre letzte Aktualisierung festlegen möchten.

git branch <branch name>

2) Suche nach der letzten Commit-ID für das Commit in einem neuen Zweig.

git log

3) Kopieren Sie die Commit-ID. Beachten Sie, dass die Liste der zuletzt verwendeten Commits oben aufgeführt wird. so können sie ihre verpflichtung finden. Sie finden das auch per Nachricht.

git cherry-pick d34bcef232f6c...

Sie können auch eine Reihe von Commits angeben.

git cherry-pick d34bcef...86d2aec

Jetzt ist deine Arbeit erledigt. Wenn Sie die richtige ID und den richtigen Zweig ausgewählt haben, werden Sie Erfolg haben. Also, bevor Sie dies tun, seien Sie vorsichtig. Andernfalls kann ein anderes Problem auftreten.

Jetzt können Sie Ihren Code drücken

git push


Um dies zu tun, ohne die Historie neu zu schreiben (dh wenn Sie die Commits bereits gedrückt haben):

git checkout master
git revert <commitID(s)>
git checkout -b new-branch
git cherry-pick <commitID(s)>

Beide Äste können dann ohne Kraft geschoben werden!





branching-and-merging