So erstellen Sie den Zweig aus einem bestimmten Commit in einem anderen Zweig

99

Ich habe mehrere Commits in der Hauptniederlassung vorgenommen und sie dann in der Entwicklungsniederlassung zusammengeführt.

Ich möchte einen Zweig aus einem bestimmten Commit im Dev-Zweig erstellen, der zuerst im Master-Zweig festgeschrieben wurde.

Ich habe die Befehle verwendet:

git checkout dev
git branch  <branch name> <commit id>

Dadurch wird jedoch der Zweig aus dem Hauptzweig erstellt, nicht der von mir erwartete Entwicklungszweig. Die Commit-ID ist im Master-Zweig und im Dev-Zweig identisch. Wie kann ich also dieselbe Commit-ID in verschiedenen Zweigen unterscheiden?

PS: Ich habe hier ein Beispiel in Github gemacht: https://github.com/RolandXu/test_for_branch

Ich habe die Befehle verwendet:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

Was ich erwarte ist, dass der Testzweig aa.txt bb.txt cc.txt enthält. Der Testzweig enthält jedoch nur aa.txt und cc.txt. Es hat höchstwahrscheinlich den Zweig aus dem Hauptzweig erstellt.

RolandXu
quelle

Antworten:

139

Wenn Sie diese branchBefehlsform (mit Startpunkt) verwenden, spielt es keine Rolle, wo Sie sich HEADbefinden.

Was machst du:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • Zuerst setzen Sie Ihre HEADauf den Zweig dev,

  • Zweitens starten Sie beim Festschreiben einen neuen Zweig 07aeec98. Bei diesem Commit gibt es keine bb.txt (gemäß Ihrem Github-Repo).

Wenn Sie einen neuen Zweig an dem Ort starten möchten, den Sie gerade ausgecheckt haben, können Sie entweder einen Zweig ohne Startpunkt ausführen:

git branch test

oder wie andere geantwortet haben, dort in einem Arbeitsgang verzweigen und auschecken:

git checkout -b test

Ich denke, dass Sie durch diese Tatsache, 07aeec98die Teil der Branche ist , verwirrt sein könnten dev. Es ist wahr, dass dieses Commit ein Vorfahr von ist dev, dessen Änderungen erforderlich sind, um das letzte Commit in zu erreichen dev. Es handelt sich jedoch um andere Verpflichtungen, die erforderlich sind, um den neuesten Stand zu erreichen dev, und diese sind nicht unbedingt in der Geschichte von 07aeec98.

8480e8ae(wo Sie bb.txt hinzugefügt haben) ist zum Beispiel nicht in der Geschichte von 07aeec98. Wenn Sie von verzweigen 07aeec98, werden die Änderungen von nicht eingeführt 8480e8ae.

Mit anderen Worten: Wenn Sie Zweig A und Zweig B in Zweig C zusammenführen und dann einen neuen Zweig mit einem Commit von A erstellen, werden die in B eingeführten Änderungen nicht angezeigt.

Hier hatten Sie zwei parallele Zweige master und dev, die Sie in dev zusammengeführt haben. Wenn Sie von einem Commit des Masters (älter als die Zusammenführung) verzweigen, erhalten Sie keine Änderungen von dev.


Wenn Sie neue Änderungen vom Master dauerhaft in Ihre Feature-Zweige integrieren möchten , sollten Sie masterdiese zusammenführen und fortfahren. Dadurch werden jedoch Zusammenführungs-Commits in Ihren Feature-Zweigen erstellt.

Wenn Sie Ihre Feature-Zweige nicht veröffentlicht haben, können Sie sie auch auf dem aktualisierten Master neu basieren : git rebase master featureA. Seien Sie bereit, mögliche Konflikte zu lösen.

Wenn Sie einen Workflow wünschen, in dem Sie Feature-Zweige ohne Merge-Commits bearbeiten und dennoch in neuere Änderungen im Master integrieren können, empfehle ich Folgendes:

  • Basieren Sie jeden neuen Feature-Zweig auf einem Commit des Masters
  • Erstellen Sie einen devZweig für ein Commit des Masters
  • Wenn Sie sehen möchten, wie sich Ihr Feature-Zweig in neue Änderungen im Master integriert, fügen Sie sowohl den Master als auch den Feature-Zweig zusammen dev.

Legen Sie sich nicht devdirekt fest, sondern verwenden Sie es nur zum Zusammenführen anderer Zweige.

Wenn Sie beispielsweise an Funktion A und B arbeiten:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

Führen Sie Zweige zu einem devZweig zusammen, um zu überprüfen, ob sie mit dem neuen Master gut funktionieren:

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

Sie können weiter an Ihren Feature-Zweigen arbeiten und neue Änderungen von Master- und Feature-Zweigen devregelmäßig zusammenführen.

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

Wenn es Zeit ist, die neuen Features zu integrieren, führen Sie die Feature-Zweige (nicht dev!) In den Master ein.

Gauthier
quelle
Vielen Dank. Du beantwortest meine Frage. Ich bin falsch im Verständnis des Git-Branch-Modus. Und haben Sie einen Vorschlag für mein Problem? Ich habe den Hauptzweig, der viele Commits rechtzeitig von anderen hat (mit Perforce synchronisieren). Ich habe einen Entwicklungszweig, in dem ich persönliche Arbeit mache. Ich möchte einen Zweig, der alle Commits von Hauptzweig und Entwicklungszweig enthält. Dann kann ich auf einfache Weise einen Zweig erstellen, der auf diesem Zweig basiert, und dann mit der spezifischen Arbeit beginnen.
RolandXu
Ich konnte nicht in einem Kommentar antworten, daher aktualisiere ich meine Antwort mit vorgeschlagenen Workflows.
Gauthier
Hey - danke für die brillante und gründliche Antwort! Nur neugierig: Warum sollte man am Ende merge the feature branches (not dev!) into master?
Cassi.lup
In der devBranche gibt es keine wirkliche Neuentwicklung . Sie sollten Ihre Filialen funktionsspezifisch halten. deventhält nur Merge Commits. Es ist sinnvoller, alle neuen Features direkt zusammenzuführen master, als die Features zusammenzuführen und dann das Ergebnis zusammenzuführen master.
Gauthier
@ Gauthier Sie haben die Frage nach dem Warum nicht angesprochen. Für mich klingt es wie eine Verschmelzung devmit nur Features A Bund Cverschmolzen in sie in masterindividuell verschmelzenden identisch ist A Bund Cin master. Wenn nicht, fordert das mein Verständnis der Funktionsweise von Git heraus und ich wäre sehr gespannt, warum!
Steven Lu
52

Sie haben die Argumente in der falschen Reihenfolge:

git branch <branch-name> <commit>

und dafür spielt es keine Rolle, welcher Zweig ausgecheckt ist; es wird tun, was du sagst. (Wenn Sie das Festschreibungsargument weglassen, wird standardmäßig ein Zweig an derselben Stelle wie der aktuelle erstellt.)

Wenn Sie den neuen Zweig beim Erstellen auschecken möchten:

git checkout -b <branch> <commit>

mit dem gleichen Verhalten, wenn Sie das Festschreibungsargument weglassen.

Cascabel
quelle
21

Sie können dies lokal tun, wie alle erwähnten

git checkout -b <branch-name> <sha1-of-commit>

Alternativ können Sie dies in Github selbst tun, indem Sie die folgenden Schritte ausführen:

1- Klicken Sie im Repository auf Commits.

2- Klicken Sie auf das Commit, von dem Sie verzweigen möchten, auf, <>um das Repository an dieser Stelle im Verlauf zu durchsuchen.

begeht Geschichte

3- Klicken Sie tree: xxxxxxoben links auf. Geben Sie einfach einen neuen Filialnamen ein und klicken Sie Create branch xxxwie unten gezeigt.

neuen Zweig erstellen

Jetzt können Sie die Änderungen lokal aus diesem Zweig abrufen und von dort aus fortfahren.

Muhammad Soliman
quelle
Dies ist, was ich brauchte .. Wie es auf der Website zu tun
eharo2
Ich habe es nie gewusst. Das ist es. GUI-Sache ist einfach toll und ich wollte weg von CLI sein.
Rohit Gupta
10

Versuchen

git checkout <commit hash>
git checkout -b new_branch

Das Commit sollte nur einmal in Ihrem Baum vorhanden sein, nicht in zwei separaten Zweigen.

Auf diese Weise können Sie dieses bestimmte Commit überprüfen und es so benennen, wie Sie möchten.

ZMorek
quelle
Hallo, ich probiere den Git Log Dev und den Git Log Master aus. Ich habe festgestellt, dass die Commit-Hash-ID für das Commit, das ich mit dem Dev-Zweig vom Master-Zweig zusammenführe,
identisch ist
Es könnte hilfreich sein, so etwas wie gitkzur Visualisierung Ihres Protokolls zu verwenden
ZMorek
Ich füge neu ein Beispiel in Github hinzu. Und Gauthier beantwortet bereits meine Frage, dass ich den Git-Branch-Modus falsch verstehe. Vielen Dank :)
RolandXu
Dies ist eine akute Antwort, denke ich. Danke
virusss8
9

Du musst:

git branch <branch_name> <commit>

(Sie haben den Filialnamen ausgetauscht und festgeschrieben)

Oder Sie können tun:

git checkout -b <branch_name> <commit>

Wenn Sie anstelle Ihres Zweignamens einen Zweig verwenden, erhalten Sie einen Zweig aus der Spitze des Zweigs.

Manojlds
quelle
Das HEADheißt nicht. Sie könnten stattdessen "die Spitze des Zweigs" oder "das Festschreiben, auf das der Zweig zeigt" sagen.
Cascabel
@Jefromi - Um Puristen zu sein, können wir nur den Zweig sagen, da der Zweig selbst ein Zeiger auf die Spitze des Zweigs ist.
Manojlds