La mia azienda sta fondendo le filiali in modo errato?


28

Di recente mi sono imbattuto in un articolo di MSDN su ramificazione e fusione e SCM: Branching and Merging Primer - Chris Birmele .

Nell'articolo dicono che 'big bang merge' è un antipasto che si fonde:

Big Bang Merge - differire la fusione dei rami fino alla fine dello sforzo di sviluppo e tentare di unire tutti i rami contemporaneamente.

Mi sono reso conto che questo è molto simile a quello che la mia azienda sta facendo con tutti i rami di sviluppo che vengono prodotti.

Lavoro in una società molto piccola con una persona che funge da revisione finale + autorità di fusione del tronco. Abbiamo 5 sviluppatori (incluso me), a ciascuno di noi verrà assegnato un compito / bug / progetto separato e ciascuno di essi si staccherà dal tronco corrente (sovversione) e quindi eseguirà il lavoro di sviluppo nel nostro ramo, testerà i risultati, scriverà la documentazione se necessario, esegui una revisione tra pari e un ciclo di feedback con gli altri sviluppatori, quindi invia la filiale per la revisione + unione sul nostro software di gestione del progetto.

Il mio capo, l'unica autorità sul repository di trunk, rimanderà effettivamente tutte le recensioni delle filiali fino a un solo momento in cui eseguirà le recensioni il più possibile, alcuni rami verranno respinti per miglioramenti / correzioni, alcuni i rami si uniranno nel tronco, alcuni rami verranno rigettati a causa di conflitti, ecc.

Non è insolito per noi avere 10-20 filiali attive nella coda di revisione finale da unire in trunk.

Inoltre, spesso dobbiamo risolvere i conflitti nella fase finale di revisione e unione perché due rami sono stati creati dallo stesso trunk ma hanno modificato lo stesso pezzo di codice. Di solito lo evitiamo semplicemente rinominando il tronco e riapplicando le nostre modifiche e risolvendo i conflitti, quindi sottoponendo il nuovo ramo per la revisione (rebase dei poveri).

Alcune domande dirette che ho sono:

  • Stiamo esibendo lo stesso anti-pattern che è stato descritto come la "fusione del big bang"?
  • Alcuni dei problemi che stiamo riscontrando sono il risultato di questo processo di unione?
  • Come possiamo migliorare questo processo di unione senza aumentare il collo di bottiglia sul mio capo?

Modifica: dubito che il mio capo allenterà la sua presa sul repository del trunk o consentirà ad altri sviluppatori di unirsi al trunk. Non sono sicuro di quali siano le sue ragioni, ma non ho davvero intenzione di sollevare l'argomento perché è stato sollevato prima e abbattuto piuttosto rapidamente. Penso che non si fidino di noi, il che non ha senso perché tutto è tracciato comunque.

Qualsiasi altra intuizione di questa situazione sarebbe apprezzata.


2
Perché la fusione è differita? Di solito, c'è un motivo per non farlo immediatamente. il ragazzo single è oberato di lavoro e l'arretrato diventa così grande? c'è qualche altro motivo per cui la fusione non viene effettuata in modo tempestivo?
Polygnome

1
Ero in una posizione simile a te, diverse volte. Per esperienza personale posso dire che molte aziende fanno il controllo delle versioni, in particolare le ramificazioni, orribilmente sbagliate.
MechMK1

3
Cosa succede quando il capo va in vacanza?
Liath

Come definiresti la strategia di branch / merge del kernel linux?
Braiam,

Le modifiche che vengono respinte a causa di conflitti ma non altri difetti devono ripetere il processo di approvazione una volta che i conflitti sono stati risolti o sono considerati "approvati provvisoriamente"?
Gregory Nisbet,

Risposte:


60

Alcuni suggerimenti:

  • Non c'è nulla di sbagliato nell'avere molte funzionalità o rami bug fintanto che le modifiche apportate in ciascun ramo sono abbastanza piccole che puoi ancora gestire i conflitti di unione risultanti in modo efficace. Questo dovrebbe essere il tuo criterio se il tuo modo di lavorare è ok, non un articolo MSDN.

  • Ogni volta che un ramo viene unito al tronco, il tronco deve essere unito al più presto in tutti i rami di sviluppo aperti. Ciò consentirebbe a tutte le persone del team di risolvere i conflitti di unione in parallelo nel proprio ramo e quindi di farsi carico del gatekeeper del bagagliaio.

  • Funzionerebbe meglio se il gatekeeper non aspettasse che 10 rami siano "pronti per la fusione nel trunk" - la risoluzione dei conflitti di fusione dalle ultime integrazioni del trunk richiede sempre un po 'di tempo per il team, quindi è probabilmente meglio lavorare a intervalli di tempo intrecciati - una integrazione da parte del gatekeeper, una nuova unione da parte del team, la successiva integrazione da parte del gatekeeper, la successiva nuova unione da parte del team e così via.

  • Per mantenere i rami piccoli, potrebbe essere utile suddividere le funzioni più grandi in più attività più piccole e sviluppare ciascuna di queste attività in un ramo a sé stante. Se la funzione non è pronta per la produzione fino a quando non vengono implementate tutte le attività secondarie, nasconderla dalla produzione dietro una funzione di attivazione / disattivazione fino al completamento di tutte le attività secondarie.

  • Prima o poi incontrerai attività di refactoring che interessano molti file nella base di codice - questi hanno un alto rischio di causare molti conflitti di unione con molti rami. Questi possono essere gestiti al meglio comunicandoli chiaramente nel team e assicurandoti di gestirli esattamente come ho scritto sopra: integrandoli prima in tutti i rami degli sviluppatori prima del reinserimento e suddividendoli in piccoli sub-refactoring.

  • Per le dimensioni della tua squadra attuale, avere un solo gatekeeper potrebbe comunque funzionare. Ma se la tua squadra crescerà di dimensioni, non c'è modo di avere un secondo gatekeeper (o più). Nota Non sto suggerendo di consentire a tutti di unirsi al tronco, ma ciò non significa che solo il tuo capo sia in grado di farlo. Probabilmente ci sono uno o due sviluppatori senior che potrebbero essere candidati anche a svolgere il lavoro di gatekeeper. E anche per le dimensioni della tua squadra attuale, un secondo gatekeeper potrebbe rendere più facile l'integrazione della tua squadra nel bagagliaio più spesso e prima o quando il tuo capo non è disponibile.


2
Penso che tu abbia il miglior commento qui, riconoscendo che non possiamo semplicemente aprire il tronco a tutti, e che la nostra pila di rami non è esattamente sempre un problema (solo quando sono in conflitto). Penso che tu abbia fatto un buon lavoro sottolineando come possiamo ridurre i conflitti e garantire che il ciclo di unione sia regolare, penso anche che tu sia completamente corretto quando dici che potremmo aver bisogno di un altro gatekeeper. Grazie mille per questa visione!
user6567423

@ user6567423 Un'altra cosa che potresti prendere in considerazione è creare filiali per ogni versione di sviluppo (ad es. 5.2.3 o qualsiasi altra cosa), di cui ogni sviluppatore può diramare per lavorare con le funzionalità e poi fondersi su, e che possono quindi essere ricollegati al principale rilasciare il ramo dal capo quando lo sviluppo è completo.
nick012000,

@ nick012000: tale suggerimento non renderebbe più difficile per il gatekeeper accettare o rifiutare i rami delle singole caratteristiche a favore / contro l'integrazione nel trunk? Voglio dire, se più funzioni si mescolassero in un ramo di sviluppo, reintegrare quei cambiamenti in parte nel tronco diventerebbe davvero difficile. Oppure mi sfugge qualcosa?
Doc Brown,

10
" risolvi unisci i conflitti in parallelo nel loro stesso ramo e quindi prendi un po 'di peso dal guardiano del bagagliaio. " - Sento che questa parte è ingiustamente ridotta a una nota a margine. "È meglio per l'azienda MA ANCHE più facile per te " sembra il principale punto di forza quando si suggerisce questo al capo. Questo va più nella direzione politica dell'ufficio, di cui SE non si occupa - ma in questa situazione, senza il consenso del capo, tutto il resto in questa risposta tecnicamente eccellente semplicemente non accadrà.
R. Schmitz,

@DocBrown Sì, lo farebbe, ma significherebbe anche che avresti molti meno conflitti tra i rami degli sviluppatori e ti darebbe comunque il grado di sicurezza dato dal non fondersi direttamente con il ramo principale - e lui può semplicemente rifiutare di accettare il lavoro come completato ed eseguire l'unione fino a quando non è soddisfatto dello stato del codice nel suo insieme.
nick012000,

18

Stiamo esibendo lo stesso anti-pattern che è stato descritto come la "fusione del big bang"?

Sembra così.

Alcuni dei problemi che stiamo riscontrando sono il risultato di questo processo di unione?

Decisamente

Come possiamo migliorare questo processo di unione senza aumentare il collo di bottiglia sul mio capo?

Nella mia azienda, ogni sviluppatore ha la capacità di fondersi. Assegniamo una richiesta di unione a un altro sviluppatore, eseguiamo il ciclo di revisione / feedback / aggiornamento fino a quando entrambe le parti non sono soddisfatte. Quindi il revisore unisce il codice.

10-20 filiali in attesa di fusione sono un segno che il processo è difettoso. Se ne avessimo così tanti, tutto il lavoro degli sviluppatori si fermerebbe fino a quando non verrà chiarito.


1
Non è la risposta che cercavo perché dubito che il mio capo allenterà la sua presa sul deposito del bagagliaio. Ma una risposta incredibilmente utile, comunque, grazie per la comprensione!
user6567423

5
@ user6567423: Se il tuo capo diventa il collo di bottiglia, che ora è secondo la tua descrizione, dovrà cambiare il suo approccio o accettare che è la causa dei ritardi (di cui i suoi dipendenti non possono essere incolpati). Rifiutare di cambiare il tuo approccio, ignorare i problemi che stai creando e spingere la colpa sugli altri non è un modo di gestire un'azienda.
Flater,

1
È d'accordo sul fatto che è il collo di bottiglia e sicuramente non incolpa gli altri per questo. Ma sì, stavo cercando consigli che potrebbero non essere immediatamente ovvi che potrebbero ridurre il nostro collo di bottiglia. Grazie per la comprensione
user6567423

1
@ user6567423 Sono curioso di sapere se ha mai spiegato perché è l'unico che può fondersi con il tronco.
Matteo,

13

Questo è essenzialmente il modo in cui funzionano molti progetti open source, incluso in particolare il kernel Linux, che ha molti più rami in volo rispetto a te in qualsiasi momento. Il modo tipico per evitare le fusioni del big bang in questi progetti è quello di creare un altro ramo (o più rami) per l'integrazione continua. Questo è il ramo che usi per assicurarti che le tue modifiche funzionino insieme ai tuoi colleghi e viene periodicamente ridisegnata sul bagagliaio quando il gatekeeper fa le revisioni.

Facoltativamente, puoi utilizzare questo ramo per combinare diverse delle tue richieste pull in un'unica grande richiesta coerente per la revisione da parte del tuo capo. Linus Torvalds riceve in genere richieste pull che sono state integrate a due o più livelli di profondità e possono avere una dimensione dell'ordine, ad esempio, di un nuovo driver di file system completo.


Grazie, penso che i suggerimenti su come combinare i rami e prevenire i conflitti saranno probabilmente il nostro miglior modo di agire.
user6567423

8

Sono d'accordo con Doc Brown ma vedo anche un altro antipattern:

Il mio capo, l' unica autorità sul repository di trunk , rimanderà effettivamente tutte le revisioni delle filiali fino a un solo momento in cui eseguirà le revisioni il più possibile, alcuni rami verranno respinti per miglioramenti / correzioni, alcuni i rami si uniranno nel tronco, alcuni rami verranno rigettati a causa di conflitti , ecc.

Nel mio umile ci sono alcuni antipasti di gestione:

  1. Lui / lei è l'unico punto di strozzatura che limita la velocità della squadra. Il tuo fattore bus è 1. La teoria dei vincoli dice che dovresti sforzarti di migliorare la parte più lenta della catena.
  2. Il tuo manager sta rallentando il tuo ciclo di feedback e riduce l'agilità del tuo team. Puoi rilasciarlo ogni settimana?
  3. La complessità delle fusioni cresce esponenzialmente con la quantità di codice. È meglio effettuare 10 fusioni con 100 righe rispetto a 1 su 1000 righe. Questo è solo uno dei motivi per cui dovresti farlo al più presto
  4. Se rilevi un guasto nel bagagliaio, lo farai in un secondo momento. Quale dei vari rami era quello problematico
  5. Le decisioni dovrebbero essere prese da coloro che hanno più conoscenza di loro. Chi ne sa di più in questo caso? Scommetto che gli sviluppatori che hanno creato il codice.
  6. Non è possibile correggere un bug in produzione se il proprio manager è in vacanza.
  7. Stai rifando il lavoro e stai gettando indietro i rami. Questa è una perdita di tempo. Anche il tempo che attende per raggiungere la produzione è uno spreco.

Raccomandazioni:

  • Il tuo manager deve delegare la responsabilità al team. Devi dimostrare che la squadra è matura, professionale. Metti in chiaro che possono fidarsi della squadra
  • Implementa un metodo di revisione. Forse hai bisogno dell'approvazione di altri due membri del team.
  • Può essere che l'utilizzo di SVN lo stia rendendo più difficile. Prova Git e vedi se ti aiuta. Ancora di più. Se usi GitHub puoi utilizzare il meccanismo Pull Request in modo che un'unione richieda determinati voti.
  • Leggi e condividi informazioni su pratiche agili, integrazione continua e DevOps.

7
Ho lavorato a livello professionale sia con SVN che con git, e direi che SVN è sicuramente parte del problema: impone una politica di merge-back-commit sui rami che non è presente in git. In effetti, tutte le fusioni sono uguali, in SVN, alcune sono più uguali di altre. Inoltre, la mancanza di commit locali rende molto più difficile sperimentare SVN che con git, e la mancanza di una zona di stadiazione non fa che aumentare la flessibilità di SVN. C'è un motivo per cui Torvalds non ha usato solo SVN invece di sviluppare git ...
cmaster

A mio avviso, Git è molto meglio di svn per i motivi presentati da @cmaster e altro ancora
reggaeguitar

Sono d'accordo che git probabilmente risolverà alcuni dei nostri problemi di fusione, e mio caro dio mi piacerebbe avere a disposizione rebase. Ma non credo che faremo presto il passaggio :(
user6567423

1
@utente6567423, ho fatto una consultazione l'anno scorso in cui ho aiutato una piccola squadra a passare da svn a Git e a cambiare il loro flusso di lavoro, incluso addestrarli su Git e configurarli con l'edizione della comunità GitLab (che è open source) per la revisione e la collaborazione del codice . Ne erano molto entusiasti; era una differenza giorno e notte. (Inoltre ci sono voluti solo tre giorni.)
Wildcard

2

Quando si esegue il lavoro di funzionalità in rami separati, non è possibile eseguire facilmente test di integrazione fino a quando uno dei rami non viene unito al trunk e inserito negli altri rami di funzionalità. Nella mia esperienza, questo è il problema principale con l'anti-pattern Big Bang Merge. Idealmente, dovresti svolgere il lavoro sulle funzionalità, testarlo nel ramo delle funzionalità, unirlo nel trunk e a quel punto hai finito con la funzione. Se non è stato unito, è necessario rivisitarlo ogni volta che qualcos'altro viene unito nel trunk prima di esso. Il dolore di questo anti-pattern è che hai molti bug di tipo integrazione che si presentano alla fine del ciclo di sviluppo.


1

Quindi hai 20 filiali. Il ramo 1 è appena unito. Quindi lo sviluppatore del ramo 2 deve unire il ramo 1 nel proprio ramo per poter unire in main senza conflitti, quindi unire. Quindi lo sviluppatore del ramo 3 deve unire il ramo 1 e il ramo 2 nel proprio ramo per poter unire in main senza conflitti, quindi si fonde.

Esercizio per il lettore: scrivere un programma che stampa il mio post completo :-)

Questa è una follia. Passerai un'incredibile quantità di tempo a fonderti.


Beh, non necessariamente, a meno che i rami non siano in conflitto, allora può semplicemente fonderli tutti nel tronco senza soluzione di continuità. Solitamente cercheremo di prevenire eventuali conflitti eseguendo un'unione di prova prima di sottoporre la filiale alla revisione, ma i conflitti sorgono inevitabilmente all'aumentare del numero di filiali nella coda. Sono d'accordo che suona come una follia però.
user6567423

2
Comportamento di fusione SVN normale, per quanto ne so ...
cmaster

0

Dato il modo in cui lavori e che il tuo capo è un maniaco del controllo responsabile, la ramificazione in sé sembra essere il problema. Invece di creare un ramo per ogni funzione, ogni sviluppatore impegna la sua funzione in parti, direttamente nel trunk. Ciò pone l'onere dell'integrazione sullo sviluppatore in più passaggi più piccoli (win-win). Il gate keeper può tenere il passo con il rilevamento di modifiche minori per un periodo più lungo prima nel ciclo di sviluppo ed essere ancora il revisore principale.

La ramificazione stessa è qualcosa che non vuoi fare a meno che tu non abbia un'ottima ragione per farlo o non hai altra opzione. Sei abbastanza piccolo da mantenere le cose sincronizzate più strettamente, il che sarà più facile e più sicuro.


1
E come gestirai il rilascio se solo 1 di queste funzionalità ha un bug o non è terminata in tempo? "La ramificazione in sé è qualcosa che non vuoi fare a meno che tu non abbia una buona ragione per farlo" - Una volta che hai 5 persone che lavorano su più funzionalità ciascuna, devi usare la ramificazione a meno che tu non abbia una ragione molto buona per non farlo.
Ivo van der Veeken,

Si trattava di due cose: il capo vuole rimanere l'unico e solo guardiano del cancello e le cose non dovrebbero divergere troppo. Sì, ci sarà un momento in cui è stato spinto qualcosa che deve ancora essere esaminato dal capo. Dovrebbe essere in grado di farlo rapidamente anche se e nell'improbabile eventualità che debba consegnare immediatamente, può annullare gli ultimi impegni. Ciò manterrà le cose sincronizzate e se fallisci in qualcosa, fallirai sicuramente velocemente. Mi sembra un buon compromesso per la situazione attuale.
Martin Maat,

1
Vorrei considerare questo come ultima risorsa
reggaeguitar
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.