2014-10-17 9 views
9

Lavoro su una squadra con un grande codice Java (300k + linee di codice), che ha recentemente adottato Git come controllo del codice sorgente (migrato da ClearCase). Stiamo usando Git Flow come nostra strategia di ramificazione. Ci sono un paio di casi d'uso che incontriamo abbastanza frequentemente con cui abbiamo lottato.Rimozione di funzionalità da versioni in Git Flow

  1. Abbiamo unito tutte le nostre caratteristiche nel ramo sviluppare per essere utilizzato in una prossima release. Quando ci avviciniamo al rilascio, risulta che una funzione non può essere pubblicata (a causa del fatto che il client non è pronto o per altri motivi). Qual è il modo migliore per creare il ramo di rilascio, ma tralasciare una funzione specifica (su molti commit)? La funzionalità deve essere disponibile per essere inclusa nella prossima versione futura. Quello che abbiamo provato prima è fare un "git revert" su tutti i commit, creare il ramo di rilascio, quindi fare un "git revert" sui commit ripristinati. Questo è un approccio piuttosto doloroso, in particolare per le grandi caratteristiche.

  2. Abbiamo già creato il ramo di rilascio, ma prima che il rilascio venga pubblicato, è determinato che una funzione deve essere rimossa. Simile al primo caso d'uso, questa funzione deve essere in grado di passare a una versione successiva. Per questo motivo, solo eseguire un "git revert" sui commit non lo risolve completamente, poiché i ripristini torneranno a fondersi nel ramo di sviluppo quando eseguiamo un "git flow release finish".

Come indicato nel modello di Git di flusso, tutti i commit sono fatte su questi rami, e mai direttamente sul ramo svilupparsi. Quando una funzionalità è completa e pronta per la prossima versione, viene quindi unita per lo sviluppo. Quando è il momento della prossima versione, il ramo di rilascio viene creato fuori dallo sviluppo. Dopo che la versione è stata sottoposta a test di regressione e risolta se necessario, passa alla produzione e viene unita al master, e torna a svilupparsi in caso di correzioni di bug e taggata con un numero di versione. I problemi di cui sopra arrivano quando una caratteristica che pensavamo andasse nella prossima versione finisce per essere lasciata fuori.

Quali sono i metodi migliori per gestire queste situazioni? In entrambi questi scenari, i rami sono stati pubblicati e abbattuti da molti sviluppatori, quindi fare confusione con la storia può creare difficoltà. So che questi sono tutt'altro che ideali, ma sfortunatamente le situazioni sono fuori dal nostro controllo.

+0

È possibile evitare di commutare direttamente su * development * e creare un ramo di rilascio a partire dall'ultima versione. In questo modo è possibile unire in modo selettivo le funzionalità che si desidera incorporare nella nuova versione. –

+0

@AndrewC Ho aggiornato la mia domanda con alcune informazioni aggiuntive. – NickForrer

+0

@Zeeker nessun commit viene effettuato direttamente sul ramo di sviluppo. Sono uniti da un ramo di funzionalità. Se uniamo feature da rilasciare invece di sviluppare, non risolve il secondo caso d'uso. – NickForrer

risposta

3

In Git un merge commit fa due cose. In primo luogo crea una cronologia di unione, quindi Git sa cosa è stato unito e cosa non è stato unito. E in secondo luogo unisce i cambiamenti di due linee di lavoro divergenti.

Puoi ingannare Git in entrambi questi aspetti, che è quello che sembra che tu debba fare. Ci sono due modi per creare la storia si fondono senza mantenere le modifiche

git merge --strategy=ours 

e

git merge 
git revert -m 1 MERGE_SHA 

Il primo crea un merge commit (e si fondono la storia), ma lascia fuori tutti i cambiamenti che normalmente sono stati uniti. In seguito crea un merge commit (e unisce la cronologia) e si fonde nelle modifiche, ma poi rimuove immediatamente tutte le modifiche preservando la prima cronologia.

Nella tua istanza, se unisci qualcosa e poi cambi idea, vorrai usare il secondo modulo e ripristinare l'unione SHA. Ora, per evitare che le modifiche di questa unione si propaghino in avanti in un altro ramo, si vorrebbe utilizzare il primo modulo. Nota che per usare efficacemente il primo modulo potresti dover unire un SHA alla volta (o usare un ramo di funzionalità aggiuntivo proprio per questo).

Quindi immaginate di avere un ramo trouble che contiene 6 commit (1-6), ed è necessario unire trouble in padrone, ma non si desidera unire le modifiche introdotte nel Commit 4. Invece di git merge trouble si farebbe do

git merge 3 # merges 1/2/3 
git merge -s ours 4 # creates merge history for 4, but does NOT merge any changes from 4 
git merge trouble # merges 5/6 
+0

Grazie per la risposta. Quando si utilizza "git merge --strategy = ours", cosa succede se ci sono correzioni di errori che vogliamo unire, ma non vogliamo anche che il revert venga unito a commit. È possibile? – NickForrer

+0

Sono curioso, come si fonderà in seguito 4 quando è pronto per essere distribuito? –

+0

probabilmente git cherry-pick funzionerebbe –

Problemi correlati