Verschieben Sie die letzten Commits mit Git in einen neuen Zweig

4985

Ich möchte die letzten Commits, für die ich mich verpflichtet habe, in einen neuen Zweig verschieben und den Master zurückbringen, bevor diese Commits gemacht wurden. Leider ist mein Git-Fu noch nicht stark genug, Hilfe?

Dh wie kann ich davon ausgehen?

master A - B - C - D - E

dazu?

newbranch     C - D - E
             /
master A - B 
Mark A. Nicolosi
quelle
114
Anmerkung: Ich fragte die entgegengesetzte Frage hier
Benjol
3
eddmann.com/posts/… dieses funktioniert
Sagar Naliyapara
7
Wurden die Kommentare hier gelöscht? Ich frage, weil ich während meines zweimonatlichen Besuchs dieser Frage immer durch diesen Kommentar scrolle.
Tejas Kale

Antworten:

6452

Umzug in eine bestehende Filiale

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

git checkout existingbranch
git merge master         # Bring the commits here
git checkout master
git reset --keep HEAD~3  # Move master back by 3 commits.
git checkout existingbranch

Die --keepOption behält alle nicht festgeschriebenen Änderungen bei, die Sie möglicherweise in nicht verwandten Dateien vorgenommen haben, oder bricht ab, wenn diese Änderungen überschrieben werden müssten - ähnlich wie dies der git checkoutFall ist. Wenn es abgebrochen wird, git stashIhre Änderungen und versuchen Sie es erneut oder verwenden Sie --hard, um die Änderungen zu verlieren (auch von Dateien, die sich zwischen den Commits nicht geändert haben!)

Umzug in einen neuen Zweig

Diese Methode erstellt einen neuen Zweig mit dem ersten Befehl ( git branch newbranch), wechselt jedoch nicht zu diesem. Dann rollen wir den aktuellen Zweig (Master) zurück und wechseln zum neuen Zweig, um weiter zu arbeiten.

git branch newbranch      # Create a new branch, containing all current commits
git reset --keep HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits
# Warning: after this it's not safe to do a rebase in newbranch without extra care.

Aber stellen Sie sicher, wie viele Commits zurückgehen. Alternativ können Sie stattdessen HEAD~3einfach den Hash des Commits (oder die Referenz wie origin/master) angeben, auf die Sie zurückgreifen möchten, z.

git reset --keep a1b2c3d4

WARNUNG: Wenn Sie mit Git Version 2.0 und höher später git rebaseden neuen Zweig auf den ursprünglichen ( master) Zweig setzen, benötigen Sie möglicherweise --no-fork-pointwährend der Rebase eine explizite Option, um zu vermeiden, dass die Commits verloren gehen, die Sie aus dem Master-Zweig verschoben haben. Das branch.autosetuprebase alwaysSetzen macht dies wahrscheinlicher. Siehe John Mellors Antwort für Details.

Duc Filan
quelle
249
Versuchen Sie insbesondere nicht , weiter zurück zu gehen als bis zu dem Punkt, an dem Sie die Commits zuletzt in ein anderes Repository verschoben haben, aus dem möglicherweise jemand anderes abgerufen hat.
Greg Hewgill
107
Ich frage mich, ob Sie erklären können, warum dies funktioniert. Für mich erstellen Sie einen neuen Zweig, entfernen 3 Commits aus dem alten Zweig, in dem Sie sich noch befinden, und überprüfen dann den von Ihnen erstellten Zweig. Wie werden die von Ihnen entfernten Commits auf magische Weise in der neuen Niederlassung angezeigt?
Jonathan Dumaine
142
@ Jonathan Dumaine: Weil ich den neuen Zweig erstellt habe, bevor ich die Commits aus dem alten Zweig entfernt habe. Sie sind immer noch in der neuen Filiale.
Sykora
86
Zweige in Git sind nur Marker, die auf Commits in der Geschichte verweisen. Es wird nichts geklont, erstellt oder gelöscht (außer den Markern)
Knittl
218
Beachten Sie auch: Tun Sie dies nicht mit nicht festgeschriebenen Änderungen in Ihrer Arbeitskopie! Das hat mich nur gebissen! :(
Adam Tuttle
1038

Für diejenigen, die sich fragen, warum es funktioniert (wie ich es 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

Nachher git branch newBranch:

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

Nachher 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. Wenn Sie newBranch erstellt haben , haben Sie einfach einen neuen Zeiger auf das letzte Commit erstellt. Dann haben git resetSie mit dem Master- Zeiger zwei Commits zurückbewegt. Da Sie newBranch jedoch nicht verschoben haben , verweist es immer noch auf das Commit, das es ursprünglich ausgeführt hat.

Ryan Lundy
quelle
56
Ich musste auch eine machen, git push origin master --forcedamit die Änderung im Haupt-Repository angezeigt wurde.
Dženan
9
Diese Antwort führt dazu, dass Commits verloren gehen: Beim nächsten Mal git rebasewerden die 3 Commits stillschweigend verworfen newbranch. Siehe meine Antwort für Details und sicherere Alternativen.
John Mellor
14
@ John, das ist Unsinn. Das Wiederherstellen, ohne zu wissen, was Sie tun, führt dazu, dass Commits verloren gehen. Wenn Sie Commits verloren haben, tut es mir leid für Sie, aber diese Antwort hat Ihre Commits nicht verloren. Beachten Sie, dass origin/masterdies im obigen Diagramm nicht angezeigt wird. Wenn Sie origin/masterdie obigen Änderungen vorgenommen und dann vorgenommen hätten, würden die Dinge sicher lustig werden. Aber das ist ein "Doktor, es tut weh, wenn ich das mache" -Problem. Und es ist nicht möglich für das, was die ursprüngliche Frage gestellt hat. Ich schlage vor, Sie schreiben Ihre eigene Frage, um Ihr Szenario zu untersuchen, anstatt diese zu entführen.
Ryan Lundy
1
@ John, in deiner Antwort hast du gesagt "Tu das nicht! git branch -t newbranch". Geh zurück und lies die Antworten noch einmal. Niemand schlug vor, das zu tun.
Ryan Lundy
1
@Kyralessa, klar, aber wenn Sie sich das Diagramm in der Frage ansehen, ist es klar, dass sie newbranchauf ihrer bestehenden lokalen masterNiederlassung basieren möchten . Nach der akzeptierten Antwort durchgeführt wird , wenn der Benutzer auf herumlaufen wird git rebasein newbranchgit wird sie daran erinnert , dass sie den vorgeschalteten Zweig zu setzen vergessen haben, so dass sie laufen werden git branch --set-upstream-to=masterdann git rebaseund das gleiche Problem haben. Sie können genauso gut git branch -t newbranchin erster Linie verwenden.
John Mellor
455

Allgemein...

Die von sykora exponierte Methode ist in diesem Fall die beste Option. Aber manchmal ist es nicht die einfachste und es ist keine allgemeine Methode. Verwenden Sie für eine allgemeine Methode Git Cherry-Pick :

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

Schritt 1 - Notieren Sie, welche Commits vom Master Sie auf einem möchten newbranch

Ausführen

git checkout master
git log

Beachten Sie die Hashes von (sagen wir 3) Commits, für die Sie möchten 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 (auf Git 1.7.2+ Bereiche verwenden)

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

Git Cherry-Pick wendet diese drei Commits auf Newbranch an.

Ivan
quelle
13
Versuchte das OP nicht, vom Master zum Newbranch zu wechseln? Wenn Sie auf dem Master Kirschbaum pflücken, würden Sie den Master-Zweig erweitern und Commits hinzufügen, die tatsächlich bereits vorhanden waren. Und es bewegt sich nicht zurück zu B. Oder gibt es etwas Feines und Cooles, das ich nicht bekomme?
RaveTheTadpole
6
Dies funktioniert sehr gut, wenn Sie versehentlich den falschen Nicht-Master-Zweig festschreiben, wenn Sie einen neuen Feature-Zweig hätten erstellen sollen.
Julianc
5
+1 für einen nützlichen Ansatz in einigen Situationen. Dies ist gut, wenn Sie nur Ihre eigenen Commits (die mit anderen durchsetzt sind) in einen neuen Zweig ziehen möchten.
Tyler V.
8
Es ist eine bessere Antwort. Auf diese Weise können Sie Commits in einen beliebigen Zweig verschieben.
Skywinder
8
Ist die Reihenfolge der Kirschernte wichtig?
Kon Psych
328

Noch eine andere Möglichkeit, dies mit nur 2 Befehlen zu tun. Hält auch Ihren aktuellen Arbeitsbaum intakt.

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 davon erfuhrgit branch -f

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 pushsein .ist ein schöner Trick zu wissen.

Aragaer
quelle
1
Aktuelles Verzeichnis. Ich denke, das würde nur funktionieren, wenn Sie sich in einem Top-Verzeichnis befinden.
Aragaer
1
Der lokale Druck ist grinsend, aber wie unterscheidet er sich von der Reflexion git branch -fhier?
Bis zum
2
@GerardSexton .ist aktueller Direktor. git kann auf REMOTES- oder GIT-URLs pushen. path to local directorywird Git URLs Syntax unterstützt. Siehe den Abschnitt GIT-URLs in git help clone.
schwächer
31
Ich weiß nicht, warum dies nicht höher bewertet wird. Ganz einfach und ohne die kleine, aber potenzielle Gefahr eines Zurücksetzens von Git - hart.
Godsmith
4
@ Godsmith Ich vermute, die Leute bevorzugen drei einfache Befehle gegenüber zwei etwas dunkeleren Befehlen. Außerdem erhalten die am besten bewerteten Antworten mehr positive Stimmen, da sie zuerst angezeigt werden.
JS_Riddler
323

Die meisten vorherigen Antworten sind gefährlich falsch!

Mach das nicht:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

Wenn Sie das nächste Mal git rebase(oder git pull --rebase) diese 3 Commits ausführen, werden diese stillschweigend verworfen newbranch! (siehe Erklärung unten)

Tun Sie stattdessen Folgendes:

git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}
  • Zuerst werden die 3 letzten Commits verworfen ( --keepist wie --hard, aber sicherer, da es fehlschlägt, anstatt nicht festgeschriebene Änderungen wegzuwerfen).
  • Dann gabelt es sich newbranch.
  • Dann werden diese 3 Commits wieder ausgewählt newbranch. Da sie nicht durch einen Zweig mehr referenziert wird, tut es , daß durch Gits mit reflog : HEAD@{2}ist der Commit , dass HEADvor 2 Operationen Bezug zu nehmen, das heißt , bevor wir 1 ausgecheckt newbranchund 2 verwendet git resetdie 3 Commits zu verwerfen.

Warnung: Das Reflog ist standardmäßig aktiviert. Wenn Sie es jedoch manuell deaktiviert haben (z. B. mithilfe eines "nackten" Git-Repositorys), können Sie die 3 Commits nach dem Ausführen nicht zurückerhalten git reset --keep HEAD~3.

Eine Alternative, die sich nicht auf das Reflog stützt, ist:

# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3

(Wenn Sie es vorziehen, können Sie @{-1}anstelle des zuvor ausgecheckten Zweigs schreiben oldbranch).


Technische Erklärung

Warum sollten git rebasedie 3 Commits nach dem ersten Beispiel verworfen werden? Es ist , weil git rebaseohne Argumente , die ermöglicht --fork-pointOption standardmäßig, die die lokale reflog verwendet , um zu versuchen , gegen den Upstream - Zweig den Zwang geschoben robust.

Angenommen, Sie haben Origin / Master abgezweigt, als er Commits M1, M2, M3 enthielt, und dann selbst drei Commits durchgeführt:

M1--M2--M3  <-- origin/master
         \
          T1--T2--T3  <-- topic

aber dann schreibt jemand die Geschichte neu, indem er origin / master zwangsweise drückt, um M2 zu entfernen:

M1--M3'  <-- origin/master
 \
  M2--M3--T1--T2--T3  <-- topic

Wenn Sie Ihr lokales Reflog verwenden, git rebasekönnen Sie feststellen, dass Sie sich von einer früheren Inkarnation des Ursprungs- / Hauptzweigs getrennt haben und daher die Commits M2 und M3 nicht wirklich Teil Ihres Themenzweigs sind. Daher wird davon ausgegangen, dass Sie M2, da es aus dem Upstream-Zweig entfernt wurde, auch nicht mehr in Ihrem Themenzweig haben möchten, sobald der Themenzweig neu basiert:

M1--M3'  <-- origin/master
     \
      T1'--T2'--T3'  <-- topic (rebased)

Dieses Verhalten ist sinnvoll und im Allgemeinen beim erneuten Basieren richtig.

Der Grund, warum die folgenden Befehle fehlschlagen:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

liegt daran, dass sie das Reflog im falschen Zustand belassen. Git sieht aus, newbranchals hätte er den Upstream-Zweig bei einer Revision, die die 3 Commits enthält, abgebrochen. Anschließend wird der reset --hardUpstream-Verlauf neu geschrieben, um die Commits zu entfernen. Wenn Sie git rebaseihn das nächste Mal ausführen , werden sie wie alle anderen Commits verworfen, die aus dem Upstream entfernt wurden.

In diesem speziellen Fall möchten wir jedoch, dass diese drei Commits als Teil des Themenzweigs betrachtet werden. Um dies zu erreichen, müssen wir den Upstream bei der früheren Revision abzweigen, die die 3 Commits nicht enthält. Das ist, was meine vorgeschlagenen Lösungen tun, daher lassen beide das Reflog im richtigen Zustand.

Weitere Informationen finden Sie in der Definition von --fork-pointin den Dokumenten git rebase und git merge-base .

John Mellor
quelle
15
Diese Antwort sagt "Tu das NICHT!" über etwas, das niemand vorschlug zu tun.
Ryan Lundy
4
Die meisten Leute schreiben die veröffentlichte Geschichte nicht um, besonders nicht auf master. Also nein, sie sind nicht gefährlich falsch.
Walf
4
@Kyralessa, das, auf das -tSie sich beziehen, git branchgeschieht implizit, wenn Sie festgelegt haben git config --global branch.autosetuprebase always. Selbst wenn Sie dies nicht tun, habe ich Ihnen bereits erklärt , dass das gleiche Problem auftritt, wenn Sie das Tracking nach dem Ausführen dieser Befehle einrichten, wie dies das OP aufgrund seiner Frage wahrscheinlich beabsichtigt.
John Mellor
2
@RockLee, ja, der allgemeine Weg, solche Situationen zu beheben, besteht darin, einen neuen Zweig (newbranch2) von einem sicheren Ausgangspunkt aus zu erstellen und dann alle Commits auszuwählen, die Sie behalten möchten (von badnewbranch bis newbranch2). Durch das Kirschpflücken erhalten die Commits neue Hashes, sodass Sie newbranch2 sicher neu starten können (und jetzt badnewbranch löschen können).
John Mellor
2
@Walf, du hast es falsch verstanden: git rebase ist robust gegen Upstreams, deren Verlauf neu geschrieben wurde. Leider wirken sich die Nebenwirkungen dieser Robustheit auf alle aus, auch wenn weder sie noch ihr Upstream jemals die Geschichte neu schreiben.
John Mellor
150

Viel einfachere Lösung mit Git Stash

Hier ist eine weitaus einfachere Lösung für Commits in den falschen Zweig. Beginnend mit einem Zweig mastermit drei falschen Commits:

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

Wann soll man das benutzen?

  • Wenn Ihr Hauptzweck das Zurückrollen ist master
  • Sie möchten Dateiänderungen beibehalten
  • Sie interessieren sich nicht für die Nachrichten auf den fehlerhaften Commits
  • Du hast noch nicht gepusht
  • Sie möchten, dass dies leicht zu merken ist
  • Sie möchten keine Komplikationen wie temporäre / neue Zweige, das Finden und Kopieren von Commit-Hashes und andere Kopfschmerzen

Was dies tut, nach Zeilennummer

  1. Macht die letzten drei Commits (und ihre Nachrichten) für rückgängig master, lässt jedoch alle Arbeitsdateien intakt
  2. Versteckt alle Änderungen an der Arbeitsdatei, sodass der masterArbeitsbaum genau dem Status HEAD ~ 3 entspricht
  3. Wechselt zu einem vorhandenen Zweig newbranch
  4. Wendet die versteckten Änderungen auf Ihr Arbeitsverzeichnis an und löscht den Stash

Sie können jetzt git addund git commitwie gewohnt verwenden. Alle neuen Commits werden hinzugefügt newbranch.

Was das nicht macht

  • Es hinterlässt keine zufälligen temporären Zweige, die Ihren Baum überladen
  • Die fehlerhaften Festschreibungsnachrichten bleiben nicht erhalten, daher müssen Sie dieser neuen Festschreibungsnachricht eine neue Festschreibungsnachricht hinzufügen
  • Aktualisieren! Verwenden Sie den Aufwärtspfeil, um durch Ihren Befehlspuffer zu scrollen und das vorherige Commit mit seiner Commit-Nachricht erneut anzuwenden (danke @ARK).

Tore

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

Ich mache das mindestens einmal pro Woche, wenn ich versehentlich neue Commits mache, masteranstatt develop. Normalerweise habe ich nur ein Commit für das Rollback. In diesem Fall ist die Verwendung git reset HEAD^von Zeile 1 eine einfachere Möglichkeit, nur ein Commit zurückzusetzen.

Tun Sie dies nicht, wenn Sie die Änderungen des Masters vorgelagert haben

Möglicherweise hat jemand anderes diese Änderungen vorgenommen. Wenn Sie nur Ihren lokalen Master neu schreiben, hat dies keine Auswirkungen, wenn er vorgelagert wird. Das Weiterleiten eines neu geschriebenen Verlaufs an Mitarbeiter kann jedoch zu Kopfschmerzen führen.

Zuschlagen
quelle
4
Danke, ich bin so froh, dass ich so viel durchgelesen habe, um hierher zu gelangen, denn es ist auch ein ziemlich häufiger Anwendungsfall für mich. Sind wir so untypisch?
Jim Mack
6
Ich denke, wir sind absolut typisch und "Ups, ich habe mich versehentlich dazu verpflichtet, es zu meistern" ist der häufigste Anwendungsfall für die Notwendigkeit, eine Handvoll oder weniger Commits zurückzusetzen. Zum Glück ist diese Lösung so einfach, dass ich sie mir jetzt merken kann.
Slam
9
Dies sollte die akzeptierte Antwort sein. Es ist einfach, leicht zu verstehen und leicht zu merken
Sina Madani
1
Ich glaube nicht, dass das Verstauen notwendig ist. Ich habe es einfach ohne gemacht und gut gearbeitet.
Ein Campos
1
Sie können Ihre Festschreibungsnachrichten auch problemlos zurückerhalten, wenn Sie sie in Ihrem CLI-Verlauf (Befehlszeilenverlauf) haben. Ich hatte zufällig sowohl die git addals auch die git commitBefehle, die ich verwendet habe, also musste ich nur den Pfeil treffen und ein paar Mal eintreten und boomen! Alles war zurück, aber jetzt auf dem richtigen Ast.
Luke Gedeon
30

Dies "bewegt" sie nicht im technischen Sinne, hat aber den gleichen Effekt:

A--B--C  (branch-foo)
 \    ^-- I wanted them here!
  \
   D--E--F--G  (branch-bar)
      ^--^--^-- Opps wrong branch!

While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)

A--B--C  (branch-foo)
 \
  \
   D-(E--F--G) detached
   ^-- (branch-bar)

Switch to branch-foo
$ git cherry-pick E..G

A--B--C--E'--F'--G' (branch-foo)
 \   E--F--G detached (This can be ignored)
  \ /
   D--H--I (branch-bar)

Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:

A--B--C--E'--F'--G'--L--M--N--... (branch-foo)
 \
  \
   D--H--I--J--K--.... (branch-bar)
Sukima
quelle
1
Können Sie nicht rebasefür das gleiche verwenden?
Bergi
Ja, Sie können rebaseim obigen Szenario alternativ den getrennten Zweig verwenden.
Sukima
24

So tun Sie dies, ohne den Verlauf neu zu schreiben (dh wenn Sie die Commits bereits verschoben haben):

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

Beide Äste können dann kraftlos geschoben werden!

teh_senaus
quelle
Aber dann müssen Sie sich mit dem Wiederherstellungsszenario befassen, das je nach Ihren Umständen viel schwieriger sein kann. Wenn Sie ein Commit für den Zweig zurücksetzen, sieht Git diese Commits weiterhin als stattgefunden an. Um dies rückgängig zu machen, müssen Sie das Zurücksetzen zurücksetzen. Dies verbrennt einige Leute, besonders wenn sie eine Zusammenführung zurücksetzen und versuchen, den Zweig wieder zusammenzuführen, nur um festzustellen, dass Git glaubt, dass dieser Zweig bereits zusammengeführt wurde (was völlig richtig ist).
Makoto
1
Deshalb wähle ich die Commits am Ende in einem neuen Zweig aus. Auf diese Weise sieht git sie als neue Commits, die Ihr Problem lösen.
teh_senaus
Dies ist gefährlicher als es zunächst scheint, da Sie den Status des Repository-Verlaufs ändern, ohne die Auswirkungen dieses Status wirklich zu verstehen.
Makoto
5
Ich folge Ihrem Argument nicht - der Sinn dieser Antwort ist, dass Sie den Verlauf nicht ändern, sondern einfach neue Commits hinzufügen (wodurch die Änderungen effektiv rückgängig gemacht werden). Diese neuen Commits können wie gewohnt verschoben und zusammengeführt werden.
teh_senaus
13

Hatte gerade diese Situation:

Branch one: A B C D E F     J   L M  
                       \ (Merge)
Branch two:             G I   K     N

Ich führte auf:

git branch newbranch 
git reset --hard HEAD~8 
git checkout newbranch

Ich habe erwartet, dass Commit ich der KOPF sein würde, aber Commit L ist es jetzt ...

Um sicherzugehen, dass Sie an der richtigen Stelle in der Geschichte landen, ist es einfacher, mit dem Hash des Commits zu arbeiten

git branch newbranch 
git reset --hard #########
git checkout newbranch
Dunkelglühen
quelle
7

Wie kann ich davon ausgehen?

A - B - C - D - E 
                |
                master

dazu?

A - B - C - D - E 
    |           |
    master      newbranch

Mit zwei Befehlen

  • Git Branch -m Master Newbranch

geben

A - B - C - D - E 
                |
                newbranch

und

  • Git Branch Master B.

geben

A - B - C - D - E
    |           |
    master      newbranch
Ivan
quelle
Ja, das funktioniert und ist ganz einfach. Sourcetree GUI ist ein wenig verwirrt über die Änderungen, die in der Git-Shell vorgenommen wurden, aber nach einem Abruf ist es wieder in Ordnung.
lars k.
Ja, sie sind wie in der Frage. Die ersten paar Diagramme sollen denen in der Frage entsprechen, nur so neu gezeichnet, wie ich es zur Veranschaulichung in der Antwort möchte. Benennen Sie den Hauptzweig grundsätzlich in newbranch um und erstellen Sie einen neuen Hauptzweig, wo Sie ihn möchten.
Ivan
4

Wenn Sie nur alle Ihre nicht gepussten Commits in einen neuen Zweig verschieben müssen , müssen Sie nur:

  1. Erstellen Sie einen neuen Zweig aus dem aktuellen:git branch new-branch-name

  2. Schieben Sie Ihren neuen Zweig :git push origin new-branch-name

  3. Setzen Sie Ihren alten (aktuellen) Zweig auf den letzten Push / Stable-Status zurück:git reset --hard origin/old-branch-name

Einige Leute haben auch andere, upstreamsanstatt originsie angemessen zu verwendenupstream

Shamsul Arefin Sajib
quelle
3

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

git checkout -b new_branch

2) Dann gehe zurück zum alten Zweig.

git checkout master

3) Git Rebase

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

4) Dann enthält der geöffnete Editor die letzten 3 Festschreibungsinformationen.

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

5) Änderung pickan dropin all den drei Commits. Speichern und schließen Sie dann den Editor.

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

6) Jetzt werden die letzten 3 Commits aus dem aktuellen Zweig entfernt ( master). Drücken Sie nun den Zweig mit dem +Vorzeichen vor dem Namen des Zweigs kräftig .

git push origin +master
Rashok
quelle
2

Sie können dies tun, ist nur 3 einfache Schritt, die ich verwendet habe.

1) Erstellen Sie einen neuen Zweig, in dem Sie das letzte Update festschreiben möchten.

git branch <branch name>

2) Suchen Sie die letzte Commit-ID für das Commit für einen neuen Zweig.

git log

3) Kopieren Sie diese Festschreibungs-ID. Beachten Sie, dass die Liste der zuletzt festgeschriebenen Festschreibungen oben steht. So können Sie Ihr Commit finden. Sie finden dies auch per Nachricht.

git cherry-pick d34bcef232f6c...

Sie können auch eine Reihe von Festschreibungs-IDs 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. Seien Sie also vorsichtig, bevor Sie dies tun. Andernfalls kann ein anderes Problem auftreten.

Jetzt können Sie Ihren Code pushen

git push

Pankaj Kumar
quelle
0

Ein anderer Weg, dies zu tun:

[1] Benennen Sie den masterZweig in Ihren um newbranch(vorausgesetzt, Sie befinden sich im masterZweig):

git branch -m newbranch

[2] Erstellen Sie einen masterZweig aus dem gewünschten Commit:

git checkout -b master <seven_char_commit_id>

zB git checkout -b master a34bc22

Saikat
quelle