Lavorare su un ramo con una dipendenza da un altro ramo che è in fase di revisione

52

In che modo git aiuta ad affrontare lo scenario seguente:

Ho un compito suddiviso in 2 parti: attività di backend e attività di frontend. Faccio una richiesta di pull per unire le modifiche del backend e attendo che venga unito (e feedback degli indirizzi). In attesa, non posso davvero lavorare sulle modifiche del frontend perché dipende dalle modifiche del backend e quelle non sono ancora disponibili sul ramo master.

Qual è il modo migliore per inserire le modifiche al ramo delle modifiche di frontend dal ramo modifiche back-end mentre è ancora in fase di revisione?

    
posta sul4bh 28.06.2017 - 02:18
fonte

7 risposte

40

Anche a volte ho questo problema. Git è molto flessibile. Ecco un modo in cui puoi farlo.

Il tuo primo ramo featureA è pronto per la revisione.

Il tuo secondo ramo featureB è in sviluppo e dipende dal codice nel ramo featureA .

Unisci il ramo featureA al ramo featureB .

Se apporti modifiche al ramo featureA , dovresti unire nuovamente il ramo featureA al ramo featureB per incorporare le modifiche.

Devi anche assicurarti di unire featureA nel tronco principale, altrimenti quando unisci featureB nel tronco principale inavvertitamente si unirà anche featureA . Una volta che featureA viene unito al tronco principale, puoi sbarazzarti del ramo featureA poiché featureB dipende solo dal tronco principale ora.

Lo preferisco quando i rami delle mie funzioni non dipendono l'uno dall'altro, ma a volte lo fanno e devi farlo rotolare.

    
risposta data 28.06.2017 - 02:43
fonte
28

Hai già un ramo da cui dipende ogni tuo ramo di funzionalità e che continua a cambiare. Si chiama master .

Il modo tipico in cui un ramo di funzione deve rimanere sincronizzato con master è di rimanere in primo piano di esso. Quando master cambia, normalmente git fetch origin master:master && git rebase master nella directory di lavoro del ramo.

Puoi fare la stessa cosa con un altro ramo di funzionalità: continua a recuperarlo e ricodificarlo su di esso.

Se, per qualche motivo, devi spostare le modifiche su un ramo diverso, puoi selezionare i i tuoi commit, che non vengono mai mescolati con i commit di altre filiali.

    
risposta data 28.06.2017 - 05:17
fonte
21

Attendi, salta fusione

Per questo approccio, fai non vuoi unire il feature_a in feature_b ripetutamente.

Il ribasamento è stato menzionato in altre risposte, ma solo per ridefinire le cose su master . Quello che vuoi fare nel tuo caso è:

  • Inizia il feature_b da feature_a , cioè:

    git checkout feature_a
    git checkout -b feature_b
    
  • Ogni volta che feature_a cambia mentre è in attesa di essere unito in master , tu rebase feature_b su di esso:

    ... commit something onto feature_a ...
    git checkout feature_b
    git rebase feature_a
    
  • Infine, non appena feature_a è stato fuso in master , ottieni semplicemente il nuovo master e rebase feature_a su di esso un'ultima volta:

    git checkout master
    git pull origin master
    git checkout feature_b
    git rebase --onto master feature_a feature_b
    

    Questo rebase finale innesterà tutti i commit che pendono dal feature_a commit (che ora è irrilevante dato che è stato fuso in master ) a destra su master . Il tuo feature_b è ora un semplice ramo standard che va da master .

EDIT: ispirato dai commenti, un po 'a testa alta: se hai bisogno di apportare qualche modifica che influenzi le caratteristiche entrambe , assicurati di farlo in feature_a (e poi rebase come mostrato ). Do non fallo in due commit diversi in entrambi i rami, anche se potrebbe essere allettante; dato che feature_a è parte della cronologia di feature_b , la singola modifica in due commit diversi sarà semanticamente sbagliata e probabilmente porterà a conflitti o "resurrezioni" di codice indesiderato, più tardi.

    
risposta data 28.06.2017 - 21:31
fonte
5

In questo caso in cui l'attività di frontend ha una dipendenza critica dal codice backend e vuoi iniziare a lavorare sul frontend prima che il backend sia finalizzato e accettato sul master, vorrei semplicemente avviare l'attività di frontend come un ramo di funzionalità in arrivo fuori dal ramo di back-end, piuttosto che ramificando il frontend sul master.

Un ramo di funzionalità che vive abbastanza a lungo ha bisogno di unire le modifiche dal master in modo occazionale (per assicurarsi di riconciliare eventuali conflitti di unione o semantici come parte del lavoro di sviluppo sul ramo di funzionalità, piuttosto che come parte della "revisione, qa , processo "merge-to-master"). Così lo fai sul tuo ramo front-end e quando il back-end è stato accettato come padrone, riceverai automaticamente eventuali modifiche minori apportate al back-end come parte della sua revisione / accettazione, per lo stesso percorso che avresti ottenere eventuali altre modifiche al codice sul master.

Se si scopre che il ramo backend ha bisogno di molto più lavoro e continua a cambiare in un periodo di tempo prima che viene unito al master (diciamo se si riscontrano problemi maggiori durante la revisione), allora probabilmente vorrai fare delle unioni periodiche direttamente dal ramo di backend nel ramo di frontend (così non continuerai a basare tutto il tuo lavoro di frontend sul codice backend obsoleto). Questo è facile se sei l'unico sviluppatore che esegue entrambe le funzioni (dal momento che sai se tu stesso apporti modifiche importanti), ma anche se entrambe le funzioni finiscono per essere elaborate in parallelo da diversi sviluppatori, dovrebbe andare bene; devi solo stare in comunicazione (che avresti comunque bisogno, se stai lavorando su attività in parallelo in cui uno ha una dipendenza critica dall'altra).

Se si scopre che l'intero ramo back-end deve essere abbandonato e non verrà mai unito (sembra che questo sarebbe un affare piuttosto importante che raramente si verificherebbe), allora puoi scegliere i tuoi commit su una nuova diramazione uscendo dal master senza il backend, o applicando reverse commit che rimuove tutto il codice backend nel ramo frontend. Ma come posso vedere, è più probabile che metta in pausa il lavoro di frontend fino a quando non capirai cosa sostituirà il backend che stai buttando fuori e poi deciderà cosa fare.

    
risposta data 28.06.2017 - 07:50
fonte
2

Non vedo il problema qui.

Lo hai già ogni volta con il tuo ramo master , che continua a cambiare mentre le funzionalità vengono sviluppate e quindi unite.

Quindi, nel tuo esempio concreto, devi prima creare il ramo feature_xxx_backend e sviluppare le modifiche del backend. Al termine, il ramo deve essere esaminato e verrà unito in master una volta completata la revisione.

Quindi, avvia semplicemente un altro ramo, feature_yyy_frontend . Probabilmente vorrai diramarti direttamente da feature_xxx_backend , in modo che tu abbia già quelle modifiche nel tuo branc. quindi semplicemente sviluppa la funzione di frontend asif il ramo erano master .

Quando il ramo feature_xxx_backend cambia, ad es. perché ci sono cose che emergono durante la revisione che devono essere indirizzate, semplicemente fai queste modifiche e uniscile nel ramo feature_yyy_frontend . Quindi continua sul ramo di frontend.

Una volta completata la revisione del ramo back-end, viene unita in master . A questo punto, sarebbe opportuno rebase il ramo feature_yyy_frontend su master , in modo che i revisori debbano solo rivedere le nuove modifiche che questo ramo contribuisce a master , e non è necessario riesaminare le modifiche apportate per il back-end (che sono già state approvate).

Questo può essere fatto anche quando hai due, tre o più rami dipendenti. Se si dispone di due diramazioni da cui si dipende, è sufficiente creare un ramo derivato in cui entrambe le funzioni sono unite. Filiale da lì, sviluppare la terza funzione, unire entrambi i rami delle caratteristiche lungo il percorso quando ognuno di questi cambia. Quando entrambe le funzioni sono state completate e integrate nel ramo derivato, rebase su quello, o se vengono unite in master, rebase su master.

Rebasing (come suggerito sopra) è davvero potente e aiuta a mantenere un registro pulito delle modifiche, rendendo le recensioni molto più semplici.

    
risposta data 28.06.2017 - 12:56
fonte
2

Come menzionato da Polygnome, puoi effettivamente unire il tuo ramo di frontend con il tuo back-end al posto dei master. Anche con l'attuale configurazione del ramo che hai ora, puoi semplicemente fare:

git checkout frontend
git merge backend

o semplicemente

git merge backend frontend

Ricorda però che se le modifiche al back-end non sono accettate e c'è bisogno di più lavoro, dovrai unire gli aggiornamenti dal back-end al frontend per evitare conflitti. Una volta che le modifiche sono state accettate nel master, puoi rebase il tuo frontend sul master per sbarazzarti del commit del backend.

Tecnicamente potresti anche fare tutto con rebase, ma questo rovinerà la cronologia dei commit del tuo branch di frontend. Da dove vengo, questa è considerata una cattiva pratica. YMMV

    
risposta data 28.06.2017 - 15:30
fonte
0

La maggior parte delle risposte qui descrive correttamente il processo di fusione delle modifiche dal secondo ramo al primo, ma non risolvono come ridurre al minimo la quantità di conflitti che potrebbe essere necessario risolvere.

Ogni volta che hai due serie di grandi cambiamenti che vuoi rivedere individualmente (come featureA e featureB ), crea un PR che NON è pensato per essere unito, ma per raccogliere un feedback anticipato su un PoC di featureA .

Le persone saranno in grado di esaminarlo rapidamente (è solo un PoC) e l'obiettivo è di convalidare la progettazione o l'approccio generale.

Quindi, puoi continuare a lavorare sulla funzione A, creare una richiesta pull per esso e ramo e lavorare sulla funzione B.

La grande differenza è che ora puoi aspettarti che featureA non cambi radicalmente: il design e l'approccio sono già stati convalidati. La revisione del codice e le modifiche richieste possono essere impercettibili e locali piuttosto che "woops, è necessario un approccio diverso". Ciò ridurrà al minimo la quantità di lavoro che devi eseguire per unire più featureB sul codice featureA , indipendentemente dal metodo scelto.

    
risposta data 03.07.2017 - 19:58
fonte

Leggi altre domande sui tag