Presentazione di una politica di diramazione del controllo versione a un piccolo team


17

Sono un appaltatore che ha recentemente iniziato con un'azienda.

Il team è composto da 3 sviluppatori composti da 2 sviluppatori junior e di livello medio, con un altro dello stesso livello che inizierà presto e io (6 anni xp). Per entrambi gli sviluppatori esistenti è il loro primo lavoro fuori dall'università / college e non hanno mai avuto uno sviluppatore senior che supervisionasse il loro lavoro prima.

Non esiste una politica esplicita di controllo della versione. Gli sviluppatori eseguono tutto lo sviluppo sul trunk e quindi si distribuiscono alla produzione direttamente dalle loro macchine di sviluppo. Il team esistente non ha familiarità con la ramificazione.

Sto cambiando tutto questo e introducendo CI, server di test TDD / staging / server di produzione ecc., Insieme a una politica di controllo della versione per completare questo.

Il sistema di controllo del codice sorgente è TFS, che non avevo mai usato prima. È configurato come un repository gigante.

Ho scritto alcuni suggerimenti per loro, ma c'è qualcos'altro che dovrei aggiungere / modificare, tenendo presente l'esperienza della squadra?

Politica di controllo della versione

Lo sviluppo è fatto sul tronco

Se si stima che una modifica richieda più di una settimana, dovrebbe essere eseguita su un ramo, con regolari fusioni dal tronco al ramo per impedire ai due di non sincronizzarsi.

Rilasciare i rami creati per il codice di produzione. Quel ramo dovrebbe contenere solo codice stabile. Possiamo avere un ramo di rilascio che viene aggiornato dal trunk una volta per sprint oppure possiamo creare un ramo di rilascio separato per ogni settimana.

Se è necessario apportare una correzione di bug urgente che influisce sul codice di produzione, viene creato sul ramo di rilascio e riunito nuovamente nel trunk.

Se adottiamo la strategia del ramo di rilascio singolo, il trunk viene unito al ramo di rilascio una volta per sprint verso la fine dello sprint.

Se adottiamo il ramo separato per strategia di rilascio, il trunk MAI verrà unito al ramo di rilascio

In alcuni scenari potrebbe essere necessario correggere il bug due volte su rami diversi, se i rami si sono differenziati troppo. Se stiamo facendo brevi sprint, questo non dovrebbe accadere troppo spesso.


Ho in programma di avere tre server. Ambiente di test che esegue sempre l'ultimo codice nel repository. Un ambiente di gestione temporanea che esegue il candidato di rilascio più recente per la gestione temporanea / test del codice del candidato di rilascio e degli scopi UAT e l'ambiente di produzione.

Il motivo per cui ho intenzione di farlo è che finora il client ha realizzato solo software interno. Il progetto più recente è per un cliente multimediale di alto profilo, e la mia sensazione è che il team debba adottare un modello di sviluppo più professionale di quello che fanno al momento.

Ad esempio, al momento, un utente può telefonare al team con una segnalazione di bug. Gli sviluppatori individuano e correggono il bug, eseguono un test rapido del bulbo oculare sui propri computer e quindi lo distribuiscono direttamente in produzione. Nessun test automatizzato o altro.


Con il senno di poi penso che il ramo delle funzionalità sia un passo troppo avanti e lo rimuoverò.

Quindi essenzialmente si riduce a) nessuna ramificazione) b) un ramo di rilascio e il tronco ec) un ramo di rilascio per rilascio e il tronco.

Mi sporgevo verso quest'ultimo. Il mio pensiero iniziale sarebbe che avrei avuto sia un candidato di rilascio che un rilascio per vivere contemporaneamente su server separati (UAT / produzione), ma effettivamente il trunk è il candidato di rilascio in qualsiasi momento, quindi un ramo per il rilascio è incline al folle. Il mio unico pensiero sarebbe se non volessimo che i nostri stakeholder vedessero il codice di sviluppo, quindi potremmo aver bisogno di un ramo candidato al rilascio separato, ma YAGNI e tutto ciò .....


3
hai preso in considerazione l'aggiunta di una spiegazione del perché hai scelto in questo modo? dire, in modo simile a come viene fatto qui . Inoltre, hai controllato la "Guida alle ramificazioni di Microsoft Team Foundation Server" (indicata ad esempio qui )?
moscerino del

3
Prova questo
gbjbaanb

1
Ricorda che sto usando TFS non un DVCS come GIT. Sembra un po 'specifico.
MrBliz,

2
La fine di quel link dice: "Tutti lavorano fuori dal trunk. Branch quando rilasci il codice. Branch un rilascio quando è necessario creare una correzione di bug per il codice già rilasciato. Branch per i prototipi." Vorrei suggerire che, per un semplice inizio, è sufficiente contrassegnare i rilasci quando si è ragionevolmente sicuri che siano Fatti. A meno che non si disponga di più sviluppatori che lavorano su più funzionalità, non è necessario disporre di più di un ramo. Tutti aggiungono funzionalità, tutti risolvono il candidato al rilascio, tutti sono d'accordo quando è pronto per taggare. Ciò significa che dovrai solo consegnare i rami per le correzioni dei bug in seguito.
TafT

1
Non mi sento a mio agio nel dargli una risposta, perché è troppo basata sull'opinione, ma ho avuto un grande successo nel convincere le persone a usare un tag "ultimo bene conosciuto" (LKG), che è un tag in movimento sul tronco che identifica l'ultimo "benedetto "versione (CCB, test, ecc.). Agli sviluppatori viene detto che le versioni verranno eseguite da questo tag LKG, non dalla testa del tronco, e oltre a ciò, sono libere di usare qualunque approccio abbia senso per loro in quel momento. Ho trovato questo schema per generare spontaneamente rami di funzionalità al momento giusto, senza alcuno sforzo iniziale o lavoro extra da parte degli sviluppatori.
Cort Ammon - Ripristina Monica il

Risposte:


16

Per un team di 3-4 sviluppatori, stai proponendo MODO troppi rami.

Ogni ramo che crei è un sovraccarico aggiuntivo che comporta un costo (tempo impiegato a fondersi, tenere traccia di ciò che è dove, ecc.). È necessario assicurarsi che il vantaggio che si ottiene dall'avere una filiale superi i costi.

Tieni presente che l'unico vero vantaggio di un ramo è l'isolamento del codice. Ciò significa che hai bisogno di una ragione concreta per voler isolare il codice.

Avere un ramo di rilascio separato per ogni sprint è folle. Perché hai bisogno del codice di uno sprint isolato dal codice per il successivo? Perché non avere un solo ramo di rilascio stabile che viene portato avanti con ogni sprint?

Se si stima che una modifica richieda più di una settimana, dovrebbe essere eseguita su un ramo, con regolari fusioni dal tronco al ramo per impedire ai due di non sincronizzarsi.

Quasi tutte le nuove funzionalità non banali impiegheranno almeno una settimana in tempo reale dopo aver tenuto conto di sviluppo, test degli sviluppatori, interruzioni quotidiane e altre attività, ecc.

Inoltre, cos'è una "fusione normale"? Quotidiano? Settimanalmente? Ogni unione che fai richiede tempo: devi assicurarti che il ramo di unione di destinazione venga compilato ed eseguito dopo le modifiche. In una piccola squadra, la fusione frequente è un sacco di spese generali.

Abbiamo un team di 4 sviluppatori che lavorano su una base di codice di oltre 1 milione di righe ed è così che operiamo:

  • Filiale principale in cui viene svolto tutto lo sviluppo
  • Un ramo per rilascio principale (fatto circa una volta all'anno)

L'unica regola principale è: non fare il check-in del codice che non viene creato.

Questo è tutto. Semplice, facile da capire, ottiene l'isolamento di cui abbiamo bisogno (in qualsiasi momento possiamo creare una build di rilascio per qualsiasi versione).

I lati positivi di tutto il lavoro di sviluppo svolto su un ramo:

  1. Gli sviluppatori sono sempre sincronizzati tra loro. Nessuna fusione dolorosa perché due sviluppatori sono rimasti nelle proprie filiali per settimane creando cambiamenti incompatibili.
  2. Le build rotte si trovano nello stesso giorno. Abbiamo una build notturna che esegue l'ultimo codice su main. Se qualcuno controlla il codice che non viene creato per qualche motivo, lo sapremo subito.
  3. Con tutti che lavorano sempre sullo stesso codice, aumenta le possibilità di trovare un bug prima piuttosto che dopo.
  4. Nessun altro overhead di fusione oltre alle correzioni mirate per rilasciare filiali. In una piccola squadra, questa è quella grande.

10
"Tieni presente che l'unico vero vantaggio di una filiale è l'isolamento del codice. Ciò significa che hai bisogno di un motivo concreto per voler isolare il codice." - Che ne dici di revisione del codice? Penso che sia una buona ragione, anche con solo due sviluppatori.
BlueRaja - Danny Pflughoeft,

2
La revisione e la ramificazione del codice non sono realmente correlate. Stai dicendo che non vuoi che il codice venga archiviato in un determinato ramo prima che venga esaminato?
17 del 26

5
@ 17of26, sì. La revisione del codice viene generalmente utilizzata come prerequisito per essere sulla linea principale. Quindi devi mostrare il codice in qualche modo prima: sul tuo monitor, in una e-mail o - in molte configurazioni - su un ramo. Funziona meglio con uno strumento di gestione dei repository come GitHub o gerrit.
Paul Draper,

3
TFS supporta la revisione del codice tramite scaffali, che sono aree di attesa temporanee nel controllo del codice sorgente. Il codice può vivere lì fino a quando non viene riesaminato e quindi archiviato.
17 del 26

2
Immagino che il punto sia che i rami non sono proprio il meccanismo giusto da usare per fare revisioni del codice.
17 del 26

31

Hai scritto alcuni suggerimenti per loro, ma non hai spiegato perché il tuo approccio sia migliore di quello che già usano . Questo può essere problematico. Se sei nello spirito "Faremo a modo mio, perché ho sei anni di esperienza professionale e tu no" (e leggendo la tua domanda, sembra esattamente così), sii pronto per essere odiato da i membri del tuo team che proveranno a fare tutto il possibile per non applicare i tuoi concetti.

Hanno un problema che deve essere risolto? È fondamentale rispondere prima a questa domanda, perché o hanno effettivamente un problema e accolgono i tuoi suggerimenti, oppure funzionano perfettamente bene come fanno attualmente, e stai semplicemente spingendo verso di loro il tuo modo di lavorare , solo perché preferisci lavorare in questo modo.

Alla fine, costringerli a utilizzare i rami può avere un impatto estremamente negativo . Lavorare con un tronco è facile, specialmente in ambiente Agile. Uno sviluppatore apporta modifiche al trunk, eventualmente gestendo piccoli conflitti e tali modifiche vengono immediatamente utilizzate dalla piattaforma di integrazione continua. Con rami:

  • Uno sviluppatore deve pensare dove dovrebbe trovarsi la modifica,

  • Qualcuno deve gestire i rami e le fusioni dai rami al tronco,

  • Le fusioni tra le filiali vengono eseguite meno frequentemente rispetto ai commit, il che significa che qualcuno deve affrontare conflitti più grandi e più difficili da gestire rispetto a un conflitto tra due commit,

  • Ogni commit non trova necessariamente la sua strada nell'integrazione continua, che ritarda le informazioni che gli sviluppatori ottengono sugli effetti che un commit può avere (specialmente le regressioni).

Il fatto che:

Il team esistente non ha familiarità con la ramificazione

peggiora le cose. Ho lavorato in una squadra di programmatori inesperti, dove un manager inesperto ha deciso di giocare con i rami. Ciò ha comportato un sacco ( molto ) tempo perso ed è esattamente la cosa che vuoi evitare per un progetto che ha scadenze.


3
Bene in questo modello, come hai intenzione di fermare la produzione di codice instabile senza diramazione?
MrBliz,

2
@MrBliz: tramite switch. È possibile attivare una funzione per gli sviluppatori, ma disattivarla per gli utenti finali se non è pronta per RTM.
Arseni Mourzenko,

3
Tenendo presente l'esperienza degli sviluppatori con cui sto lavorando e l'attuale mancanza di test automatizzati, non penso che sarebbe una buona idea per la nostra situazione.
MrBliz,

4
@MrBliz impedisci al codice instabile di entrare in produzione isolandolo nei rami di rilascio (questo è esattamente il suo scopo) e testandolo . I rami delle caratteristiche non aiutano in questo; in realtà, questi comportano un rischio maggiore di introdurre instabilità in caso di grandi fusioni non integrate, difficili da controllare
moscerino

1
@MrBliz, sì, l'ho notato (e penso che tu l'abbia capito bene, anche se solo hai mancato di spiegare il ragionamento per supportarlo). È solo che né il tuo commento né questa risposta menzionano esplicitamente se si tratta di rilascio o rami di funzionalità (o entrambi?), Quindi ho commentato per sottolineare la differenza . Il fatto che FWIW sia vago su questo è probabilmente l'unica cosa che non mi piace di questa risposta
moscerino del

3

Come dice Mainma, fai attenzione alla ramificazione. Citi la ramificazione ogni poche settimane, è davvero necessario avere molte filiali?

In alternativa, potresti anche avere un modello 'pull' invece di un modello push. Se stavi usando Git o Mercurial, potresti avere un server di integrazione che convalida le loro modifiche prima di inviare al server centrale. In TFS, puoi fare qualcosa di simile usando i check-in con gate . In questo modo, puoi avere la convalida ed evitare la complessità dei rami.


In effetti ci sarebbero solo tre rami attivi (rilascio, candidato al rilascio e trunk) alla volta, e il più delle volte solo il ramo di rilascio e il trunk.
MrBliz,

I vecchi rami verranno eliminati in TFS o nascosti in modo più accurato.
MrBliz,
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.