2012-09-10 4 views
29

Ich versuche, einem Mitarbeiter zu helfen, der versehentlich einen Feature-Zweig aus einem anderen Feature-Zweig erstellt hat, anstatt den zweiten Master zu erstellen. Hier ist im Wesentlichen, was wir jetzt haben ...Split ein Git Zweig in zwei Zweige?

Master ---A---B---C 
        \ 
       Foo E---F---F---H 
           \ 
          Bar J---K---L---M 

Und hier ist das, was wir würden gerne haben ...

Master ---A---B---C 
        |\ 
      Foo | E---F---F---H 
        | 
      Bar J---K---L---M 

Ein Weg, dachte ich wäre FooV2 und BarV2 Zweige zu schaffen, und Kirsch- Wählen Sie die einzelnen Commits in die entsprechenden V2-Zweige. Aber ich bin neugierig, gibt es einen besseren Weg, um mit dieser Situation umzugehen?

git rebase --onto C H M 

Wenn einige Patches Konflikt, können Sie sie manuell zu lösen haben (aber man muss auch tun, wenn Rosinenpickerei):

Antwort

12

Es sieht für mich wie Sie konnte:

git checkout J 
git rebase master 

Edit:

Ich habe versucht, was ich vorgeschlagen und es funktioniert nicht. knittls Vorschlag funktioniert nicht (auf meiner Box). Hier ist, was für mich arbeiten:

git rebase --onto master foo bar 
+2

Vielen Dank; Die bearbeitete Version hat super funktioniert! Für den Fall, dass jemand mehr Details dazu benötigt, gibt es einen Abschnitt "Weitere interessante Abzüge" im Pro Git Buch, der fast genau dieses Beispiel abdeckt: http://git-scm.com/book/en/Git-Branching- Rebasing –

+1

'git rebase --auf master foo bar' bedeutet: Nimm" bar "ohne" foo "und lege es auf den Master – schoetbi

6

Sie können Ihre Bar Zweig auf Master rebase. Vorsicht: Rebase nicht, wenn der Verlauf bereits veröffentlicht wurde.

57

Für eine allgemeine Antwort, die uns die Dinge ein wenig besser als nur zu verstehen, wird dazu beitragen, „diesen Befehl ausführen“, wir brauchen ein größeres Beispiel. Also, lasst uns so tun, als Sie tatsächlich in dieser Situation sind:

---A---B---C <= Master 
      \ 
      E---F---F---H <= Foo 
          \ 
          J---K---L---M <= Bar 
             \ 
             N---O---P---Q <= Baz 

Und hier ist das, was wir haben möchten ...

---A---B---C <= Master 
      |\ 
      | E---F---F---H <= Foo 
      |\ 
      | J---K---L---M <= Bar 
      \ 
      N---O---P---Q <= Baz 

Zum Glück hat Git eine Lösung für uns in den Optionen die rebase Befehl!

git rebase --onto [newParent] [oldParent] [branchToMove] 

Was dies bedeutet, gliedert sich in Teile werden können:

  1. rebase - Ändern Sie die Eltern von etwas
  2. --onto - Dies ist die Flagge, die git erzählt diese alternative Fütterungsmaterial Syntax zu verwenden
  3. newParent - Dies ist die Verzweigung, die die Zweigstelle, die Sie reSaining haben, als übergeordnete
  4. hat
  5. oldParent - Dies ist der Zweig ist, dass der Zweig Sie gerade Rebasing hat, wie es Eltern
  6. branchToMove - Dies ist der Zweig, den Sie (Rebasing)

Die etwas über „alte Mutter Zweig“ bewegen kann ein wenig verwirrend sein, aber was es wirklich macht ist, dass es sagt: "Ignoriere die Änderungen von meinem alten Elternteil, wenn du die Rebase machst". Die oldParent ist, wie Sie definieren, wo der Zweig, den Sie bewegen (dh branchToMove) beginnt.

Also, was sind die Befehle in unserer Situation auszuführen?

git rebase --onto Master Bar Baz 
git rebase --onto Master Foo Bar 

Beachten Sie, dass die Reihenfolge dieser Befehle Rolle, weil wir uns abzweigen des Ende der „Zweigkette“ ziehen müssen.

+3

Nimmt im besten Sinne den ganzen Zauber heraus. Ich nutze das einfach zu un-fubar (baz), einem Feature-Zweig, wo ich etwas an Foo gearbeitet habe, dann einige Commits in Richtung Bar, dann einige mehr Foo, aber alle auf derselben Commit-Linie. #fail –

+1

Ausgezeichnete Antwort. –

+0

@cdeszaq Ich habe versucht, zu bearbeiten, aber nicht sicher, was passiert ist, im ersten Diagramm gibt es zwei "Bar" Zweige, wenn der erste "Foo" sein sollte, um den Rest Ihrer Antwort und der ursprünglichen Frage zu entsprechen. – ryanwils