2011-12-22 7 views
11

Abbiamo appena iniziato a utilizzare git per il nostro codice di produzione e stiamo riscontrando un leggero problema nel nostro flusso di lavoro. Dobbiamo capire come gestire i miglioramenti generali del codice/le correzioni del debito tecnico che emergono mentre si lavora su una funzione.Rami di funzionalità Git e miglioramenti minori del codice

Il flusso di lavoro che abbiamo adottato consiste nell'utilizzare lo "sviluppo" come principale ramo dell'integrazione e sviluppare tutte le funzionalità sui rami di funzionalità da "sviluppare". Quando una funzionalità è completa, lo sviluppatore crea una richiesta di pull e tutti la esaminano per fornire commenti prima che vengano uniti in fase di sviluppo. Questo sembra funzionare molto bene.

Il problema è che durante lo sviluppo di routine di una funzione, lo sviluppatore può finire per voler modificare/rifattorizzare un codice comune per migliorare il sistema o eliminare alcuni debiti tecnici. Questo cambiamento è prezioso, ma non direttamente legato alla funzionalità in fase di sviluppo.

Sulla base del nostro flusso di lavoro, dovrebbe essere fatto su un ramo diverso che passa attraverso la propria richiesta pull e revisione del codice prima di entrare in sviluppo. Se li facciamo fare però, come possono ottenere il cambiamento sul loro ramo di funzionalità nel frattempo mentre aspettano che la revisione completa del codice avvenga e il codice da incorporare per lo sviluppo.

Le idee che abbiamo sono:

1) cherry-pick le modifiche dal ramo 'refactorX' nel nostro ramo di caratteristica. Continua a sviluppare e lascia che git (si spera) capisca quando ci uniamo indietro per sviluppare che ha già il cambio dal ramo del refactoring.

2) Unire il ramo "refactorX" nel nostro branch di funzionalità e continuare lo sviluppo. (nota: lo sviluppo di ramo per "refactoringX" potrebbe essere stato più avanti nella storia dello sviluppo, quindi pensiamo che questo potrebbe avere problemi)

3) Un'altra opzione più intelligente che non conosciamo ancora. :)

Quello che stiamo cercando è una guida alle migliori pratiche su come gestire questa parte del flusso di lavoro. Dopo averne parlato di più, sappiamo che verrà fuori frequentemente e vogliamo trovare un modo semplice ed efficiente per gestirlo nel nostro flusso di lavoro.

Qualche consiglio?

+0

L'opzione 2 sembra soddisfacente, quali problemi si prevedono? – fge

+0

L'opzione 2 sembra discutibile, perché stai incorporando tutte le modifiche successive da 'sviluppo' nel tuo ramo delle funzionalità quando lo fai (come osserva Allen). L'opzione 1 mi sembra comunque buona. –

+0

Un'altra preoccupazione per 1 & 2: non voglio che le modifiche selezionate/unite nel ramo della funzione vengano visualizzate nelle differenze utilizzate per la revisione del codice della richiesta pull. Non riesco a pensare a un buon modo per farlo, anche se senza una ridefinizione. E dal momento che questa è una branca "pubblica" spinta al ripopolamento della società centrale, la ridefinizione sembra una "cattiva idea". – Allen

risposta

2

Sembra che si sta tentando di evitare la fusione del ramo di sviluppare di nuovo nel ramo della funzione. È utile evitare questo passaggio, ma a volte è necessario, specialmente in situazioni come questa.

Una tecnica che stiamo iniziando a utilizzare è git rebase --onto. Invece di unire il ramo di sviluppo al ramo di funzionalità, il ramo di funzionalità può essere spostato alla fine del ramo di sviluppo per acquisire le nuove funzionalità.

Quando si utilizza un repository centrale, è probabilmente più utile creare un nuovo nome di ramo di feature. Ad esempio aggiungiamo -v2 al nuovo nome del ramo.

Il processo tipico mossa potrebbe apparire come

git checkout feature 
git branch -m feature-v2 
git rebase --onto develop develop 
git push -u origin feature-v2 

Ora avete nuovo codice nel tuo ramo della funzione, ma non si sono fuse il ramo svilupparsi in funzione del ramo.

+1

Idea interessante. Non avevo pensato di creare in modo efficace un nuovo branch di funzionalità subito prima della richiesta di pull e quindi di ridistribuirlo in modo che contenga solo le modifiche che non ho selezionato/unito da qualcosa che è già stato sviluppato. Ci sono degli svantaggi di questo approccio? (l'unica cosa a cui riesco a pensare è che i timestamp per i commit su questa nuova funzione non saranno ancora attivi o rimarranno nel momento in cui è stata apportata la modifica originale?) – Allen

+0

git manterrà i commit esattamente com'erano quando erano sono stati originariamente fatti. I timestamp e i messaggi di commit sono tutti mantenuti. L'unica differenza (e questo è importante) è che i commit sono diversi. Questo è che hanno numeri di hash diversi. –

+0

Ho una modifica su questa risposta in cui ho documentato una variazione che ha funzionato perfettamente per noi. Speriamo che la modifica arriverà presto ... – Allen

3

Una terza opzione è per lo sviluppatore di rebase tutte le loro filiali di funzionalità sul ramo che è stato refactored (quindi le modifiche di refactoring sono incorporate in tutto il loro lavoro). Quindi assicurati che il ramo di refactoring venga esaminato per primo e unirlo nuovamente al ramo di sviluppo. Tutti i rami delle funzionalità saranno quindi basati sullo sviluppo e sarà possibile unirli come faresti normalmente (cioè unire uno, rebase gli altri sullo sviluppo, ripetere).

In arte ASCII, prima di refactoring recensendo:

--- development 
       \ 
       --- refactoring 
           \ 
           --- feature1 
           --- feature2 

E poi:

------ development|refactoring 
           \ 
           --- feature1 
           --- feature2 

Quindi, se hai finito feature1 e unire in:

------ refactoring --- development|feature1 
        \ 
        --- feature2 

È rebase feature2 sullo sviluppo di nuovo:

------ refactoring --- development|feature1 
              \ 
              --- feature2 

E poi è possibile unire feature2 come al solito:

------ refactoring --- feature1 --- development|feature2