Come creare il ramo da un commit specifico in un ramo diverso


102

Ho eseguito diversi commit nel ramo master e poi li ho uniti al ramo dev.

Voglio creare un ramo da un commit specifico nel ramo dev, che è stato prima eseguito il commit nel ramo master.

Ho usato i comandi:

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

Tuttavia, questo crea il ramo dal ramo master, non il ramo dev che mi aspettavo. L'ID commit è lo stesso nel ramo master e nel ramo dev. Quindi, come posso distinguere lo stesso ID commit in un ramo diverso?

PS: ho fatto un esempio in github qui https://github.com/RolandXu/test_for_branch

Ho usato i comandi:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

Quello che mi aspetto è che il ramo di test contenga aa.txt bb.txt cc.txt. Tuttavia, il ramo di prova contiene solo aa.txt e cc.txt. Molto probabilmente ha creato il ramo dal ramo principale.

Risposte:


145

Se stai usando questa forma del branchcomando (con punto di inizio), non importa dove ti HEADtrovi.

Cosa stai facendo:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • Per prima cosa, imposti il ​​tuo HEADsul ramo dev,

  • In secondo luogo, si avvia un nuovo ramo su commit 07aeec98. Non c'è bb.txt in questo commit (secondo il tuo repository GitHub).

Se vuoi avviare un nuovo ramo nella posizione che hai appena estratto, puoi eseguire branch senza punto di partenza:

git branch test

o come altri hanno risposto, diramazione e checkout lì in un'unica operazione:

git checkout -b test

Penso che potresti essere confuso dal fatto che 07aeec98fa parte del ramo dev. È vero che questo commit è un antenato di dev, le sue modifiche sono necessarie per raggiungere l'ultimo commit in dev. Tuttavia, sono altri impegni necessari per raggiungere l'ultimo dev, e questi non sono necessariamente nella storia di 07aeec98.

8480e8ae(dove hai aggiunto bb.txt), ad esempio, non è nella cronologia di 07aeec98. Se ti dirigi da 07aeec98, non otterrai le modifiche introdotte da 8480e8ae.

In altre parole: se unisci il ramo A e il ramo B nel ramo C, quindi crei un nuovo ramo su un commit di A, non otterrai le modifiche introdotte in B.

Lo stesso qui, avevi due rami paralleli master e dev, che hai unito in dev. La ramificazione da un commit di master (precedente all'unione) non fornirà le modifiche di dev.


Se vuoi integrare in modo permanente le nuove modifiche dal master nei rami delle tue funzionalità, dovresti unirli mastere andare avanti. Tuttavia, questo creerà commit di unione nei rami delle funzionalità.

Se non hai pubblicato i tuoi caratteristica rami, si può anche rebase sul master aggiornato: git rebase master featureA. Preparati a risolvere possibili conflitti.

Se desideri un flusso di lavoro in cui puoi lavorare su rami di funzionalità senza merge commit e integrarti comunque con le modifiche più recenti nel master, ti consiglio quanto segue:

  • basare ogni nuovo ramo di funzionalità su un commit di master
  • creare un devramo su un commit di master
  • quando hai bisogno di vedere come il tuo ramo di funzionalità si integra con le nuove modifiche in master, unisci sia master che il ramo di funzionalità in dev.

Non impegnarti devdirettamente, usalo solo per unire altri rami.

Ad esempio, se stai lavorando sulle funzioni A e B:

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

Unisci i rami in un devramo per verificare se funzionano bene con il nuovo master:

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

È possibile continuare a lavorare sui rami delle funzionalità e continuare a unire devregolarmente le nuove modifiche sia dai rami principali che da quelli delle funzionalità .

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

Quando è il momento di integrare le nuove funzionalità, unisci i rami delle funzionalità (non dev!) In master.


Grazie. Rispondi alla mia domanda. Ho sbagliato a capire la modalità git branch. E hai qualche suggerimento per il mio problema. Ho il ramo principale che ha molti commit tempestivi da altri (sincronizza con forza). Ho un ramo di sviluppo, faccio un lavoro personale. Voglio un ramo che contenga tutti i commit del ramo master e del ramo dev, quindi posso creare facilmente un ramo basato su questo ramo, quindi iniziare a lavorare in modo specifico.
RolandXu

Non ho potuto rispondere in un commento, quindi aggiorno la mia risposta con i flussi di lavoro suggeriti.
Gauthier

Ehi, grazie per la risposta brillante e completa! Solo curioso: alla fine, perché uno dovrebbe merge the feature branches (not dev!) into master?
cassi.lup

Non c'è un vero nuovo sviluppo nel devramo. Dovresti mantenere specifiche le funzionalità dei tuoi rami. devcontiene solo commit di unione. Ha più senso unire tutte le nuove funzionalità direttamente master, piuttosto che unire le funzionalità e poi unire il risultato in master.
Gauthier

@Gauthier Non hai affrontato la domanda sul perché. Per me suona come fondere un devcon solo caratteristiche A Be Cfuse in esso masterè identico a fondere individualmente A Be Cin master. In caso contrario, ciò sfida la mia comprensione di come funziona git e sarei molto curioso di sapere perché!
Steven Lu

53

Hai gli argomenti nell'ordine sbagliato:

git branch <branch-name> <commit>

e per questo, non importa quale ramo viene estratto; farà quello che dici. (Se ometti l'argomento commit, per impostazione predefinita viene creato un ramo nello stesso posto di quello corrente.)

Se vuoi controllare il nuovo ramo mentre lo crei:

git checkout -b <branch> <commit>

con lo stesso comportamento se ometti l'argomento commit.


22

Puoi farlo localmente come tutti hanno menzionato usando

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

In alternativa, puoi farlo in GitHub stesso, segui i passaggi:

1- Nel repository, fare clic su Commits.

2- sul commit da cui si desidera eseguire il branch, fare clic su <>per navigare nel repository a questo punto della cronologia.

impegna la storia

3- Fare clic su tree: xxxxxxin alto a sinistra. Basta digitare un nuovo nome di ramo lì fare clic Create branch xxxcome mostrato di seguito.

creare un nuovo ramo

Ora puoi recuperare le modifiche da quel ramo localmente e continuare da lì.


Questo è ciò di cui avevo bisogno .. Come farlo nel sito web
eharo2

Non l'ho mai saputo. Questo è. La cosa della GUI è semplicemente fantastica e volevo essere lontano dalla CLI.
Rohit Gupta

10

Provare

git checkout <commit hash>
git checkout -b new_branch

Il commit dovrebbe esistere solo una volta nel tuo albero, non in due rami separati.

Ciò ti consente di controllare quel commit specifico e nominarlo come vuoi.


ciao provo git log dev e git log master, ho trovato l'id hash del commit è lo stesso per il commit che
unisco

potrebbe essere utile usare qualcosa come gitkvisualizzare il registro
ZMorek

Ho appena aggiunto un esempio in github. E Gauthier ha già risposto alla mia domanda che fraintendo la modalità git branch. Grazie :)
RolandXu

Questa è una risposta acuta, credo. Grazie
virusss8

9

Devi fare:

git branch <branch_name> <commit>

(stavi scambiando il nome del ramo e il commit)

Oppure puoi fare:

git checkout -b <branch_name> <commit>

Se al posto di si usa il nome del ramo, si ottiene un ramo dalla punta del ramo.


Non è questo che HEADsignifica. Potresti invece dire "la punta del ramo" o "il commit a cui punta il ramo".
Cascabel

@ Jefromi - Per essere puristi, possiamo dire solo il ramo, poiché il ramo stesso è un puntatore, beh, la punta del ramo.
manojlds
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.