I DVCS scoraggiano l'integrazione continua?


34

Supponiamo che ci sia un team di dieci sviluppatori agili. Ogni giorno scelgono un'attività dal consiglio di amministrazione, commettono diverse modifiche contro di essa, fino a quando (entro la fine della giornata) hanno completato l'attività. Tutti gli sviluppatori effettuano il check-in direttamente sul trunk (in stile Google, ogni commit è un candidato al rilascio, utilizzando gli interruttori di funzionalità ecc.).

Se utilizzavano un CVS centralizzato come SVN, ogni volta che uno di loro si impegna, il server di build si integra e verifica le proprie modifiche rispetto al lavoro degli altri nove sviluppatori. Il server di build funzionerà praticamente ininterrottamente tutto il giorno.

Ma se stessero usando un DCVS come git, lo sviluppatore potrebbe attendere fino al completamento dell'attività prima di raggruppare tutti i propri commit locali nel repository centrale. I loro cambiamenti non saranno integrati fino alla fine della giornata.

In questo scenario, il team SVN si sta integrando continuamente più frequentemente e sta scoprendo problemi di integrazione molto più velocemente rispetto al team git.

Questo significa che i DVCS sono meno adatti per i team continui rispetto ai vecchi strumenti centralizzati? Come potete aggirare questo problema della spinta differita?


15
Le persone si impegneranno almeno una volta prima di completare l'attività durante l'utilizzo di SVN? E le persone spingeranno solo una volta al giorno quando si usa un DVCS? Il tuo ragionamento presuppone che nessuno dei due sia vero, ma la mia impressione indica diversamente.

3
Ottima domanda
Michael Brown,

1
@delnan: supponiamo che entrambe le squadre si impegnino più volte al giorno, ma i ragazzi git spingono insieme quei commit solo quando l'attività è completata.
Richard Dingwall,

2
Penso che tu stia guardando l'estremità sbagliata del tubo, hai problemi, non se non spingi fino al completamento, ma se non tiri regolarmente durante lo sviluppo
jk.

2
Ho visto il contrario: gli sviluppatori che usano un sistema centralizzato di controllo del codice sorgente come TFS si impegnano raramente, perché il loro codice influenza tutti quando lo fanno. Finiscono per salvare temporaneamente il loro lavoro negli scaffali dei mostri e quando hanno finito, tutto va in un unico mostro.
Kyralessa,

Risposte:


26

Disclaimer: lavoro per Atlassian

DVCS non scoraggia l'integrazione continua finché lo sviluppatore spinge in remoto su base regolare verso il proprio ramo e il server CI è configurato in modo da creare i rami attivi noti.

Tradizionalmente ci sono due problemi con DVCS e CI:

  • Incertezza dello stato di integrazione - a meno che lo sviluppatore non si sia unito regolarmente dal master ed abbia eseguito la build, non si conosce lo stato delle modifiche combinate. Se lo sviluppatore deve farlo manualmente, è probabile che non sarà fatto abbastanza spesso per raccogliere i problemi abbastanza presto.
  • Duplicazione e deriva della configurazione della build : se la configurazione della build deve essere copiata da una build 'master' per creare una build del ramo, la configurazione per il ramo può diventare rapidamente non sincronizzata con la build da cui è stata copiata.

In Bamboo, abbiamo introdotto la possibilità per il server di build di rilevare nuovi rami mentre vengono creati dagli sviluppatori e di impostare automaticamente le build per il ramo in base alla configurazione di build per il master (quindi, se si cambia master config build, cambia anche la configurazione dei rami per riflettere il cambiamento).

Abbiamo anche una funzione chiamata Unisci strategie che può essere utilizzata per aggiornare il ramo con le modifiche dal master prima dell'esecuzione della generazione del ramo o per inviare automaticamente le modifiche in un ramo della build di successo al master, assicurando che le modifiche tra i rami vengano testate insieme il più presto possibile .

Ad ogni modo, se sei interessato a saperne di più, vedi il mio post sul blog "Rendere efficaci i rami delle funzionalità con l'integrazione continua"


14

La mia piccola squadra è passata a un DVCS un anno o due fa, e il resto della mia compagnia ha seguito l'esempio un paio di mesi fa. Nella mia esperienza:

  • Le persone che usano un VCS centralizzato tendono ancora a trattenersi dagli impegni quando stanno facendo un grande progetto. Questo non è un problema esclusivo dei DVCS. Avranno set di modifiche che attendono diversi giorni prima di eseguire un commit. La grande differenza è che se fanno un errore ad un certo punto durante questo periodo, o se il computer si arresta in modo anomalo, richiede molto più sforzo per risolverlo.
  • Utilizziamo un flusso di lavoro di commit in cui ogni sviluppatore lavora sul proprio ramo denominato e solo la persona che ha esaminato il proprio codice è autorizzata a unire le proprie modifiche alla testa. Ciò riduce la probabilità che un commit causi problemi, quindi le persone prestano davvero attenzione quando il server di generazione produce un messaggio di errore. Significa anche che altri sviluppatori possono continuare a lavorare sui propri rami fino a quando la testa non viene riparata.
  • Su un DVCS, le persone tendono a dedicare più tempo alla programmazione prima di fondere il loro codice con la testa. Quindi tende a introdurre un piccolo ritardo nella continuità della build. Ma la differenza non è abbastanza significativa per contrastare i vantaggi del DVCS.

Il server di compilazione crea tutti i rami nominati in modo che ogni committer abbia il proprio lavoro di compilazione del server?

Il revisore del codice non diventa un serio collo di bottiglia in questo scenario?
Andres F.

@ ThorbjørnRavnAndersen: No, il server di compilazione crea solo il ramo "head" o "default" e i rami di rilascio. Quindi ogni utente può impegnarsi nel proprio ramo senza paura di interrompere la build. Potremmo concepire un server di compilazione per costruire i rami di tutti, ma in alcuni casi voglio impegnare un po 'di lavoro che ho fatto, sapendo benissimo che mette il mio ramo in uno stato inutilizzabile. Mi assicurerò che il mio ramo sia stabile prima di fare una revisione del codice e unirmi. Mi interessa solo che i rami principali che tutti gli altri usano siano stabili.
StriplingWarrior,

@AndresF .: No, non è diventato un serio collo di bottiglia per noi. Per prima cosa, abbiamo più persone che possono fare revisioni del codice, quindi ogni sviluppatore di solito può trovare almeno un revisore che è disponibile per una revisione in qualsiasi momento. Inoltre, parte della bellezza di un DVCS è che anche se non puoi unirti subito, puoi iniziare a lavorare su qualcos'altro e altri sviluppatori possono unire le tue modifiche nei loro rami se dipendono dalle tue modifiche per il loro lavoro. Dopo aver esaminato il codice, esiste un nodo specifico del changeset in cui il revisore può unirsi.
StriplingWarrior,

13

Di recente ho osservato circa 19 progetti che utilizzavano Mercurial over SubVersion (ero un fanatico della sovversione ): gli sviluppatori hanno iniziato a diventare davvero individualisti lavorando sul proprio ramo e integrandosi solo dopo giorni o settimane serverali. Ciò ha causato seri problemi di integrazione e preoccupazioni.

Un altro problema che abbiamo riscontrato è con il server di integrazione continua. Siamo stati informati di problemi (ad esempio test non riusciti), solo quando è stata effettuata la sincronizzazione dei commit sul server.

Sembra che Martin Fowler ne abbia scritto sul suo sito.

Detto questo, alcuni dei progetti che cito hanno fatto una sincronizzazione almeno una volta al giorno riducendo i problemi. Quindi, per rispondere alla tua domanda, penso che il DVCS possa scoraggiare l'integrazione continua e aumentare l'individualismo. Tuttavia, DVCS non è la causa diretta.

Lo sviluppatore è ancora in carica indipendentemente dal VCS che usano.


Detti progetti hanno enfatizzato un obiettivo comune o gli sviluppatori hanno dovuto lavorare su obiettivi specifici e disconnessi?

Non possiamo generalizzare su 19 progetti. Ma quando abbiamo affrontato problemi di integrazione, anche perché alcuni principi come la separazione delle preoccupazioni non sono stati rispettati. Quello che dico è che, sì, DVCS sembra incoraggiare l' individualismo e ridurre i benefici dell'integrazione continua, ma, se gli sviluppatori sono ben addestrati, è possibile ridurre o eliminare il problema.

In tal caso, suggerirei di effettuare anche consegne continue, o almeno consegne frequenti ai clienti, quindi il termine per la fusione DEVE avvenire è molto più breve. L'hai fatto in questi progetti?

Naturalmente, usiamo Scrum

1
Stavo cercando la tua definizione di consegna continua (ancora non riesco a trovare qualcosa di decente, apprezzerò se potessi darmi dei riferimenti), e ho trovato questo: continuousdelivery.com/2011/07/…

10

L'idea su cui basare il tuo ragionamento è molto traballante, a bassa voce. È questione di team / gestione / processo che lo sviluppatore può attendere fino al completamento dell'attività .

Farlo in un modo o nell'altro, "aspettare" o "sbrigarsi", tronco condiviso o ramo isolato, è noto come strategia di ramificazione e se studi informazioni disponibili online , scoprirai che la scelta di una particolare strategia non ha praticamente nulla a che fare con VCS essendo centralizzato o distribuito.

Ad esempio, per VCS distribuiti come Mercurial, puoi facilmente trovare una forte raccomandazione per le fusioni frequenti :

Innanzitutto, unisci spesso! Questo rende la fusione più facile per tutti e scopri i conflitti (che sono spesso radicati in decisioni di progettazione incompatibili) prima ...

Studiando raccomandazioni come sopra, si può facilmente scoprire che fanno appello a considerazioni che non hanno nulla a che fare con la distribuzione di Mercurial.

Vediamo ora la situazione a fianco del VSC centralizzato, Subversion. Studiando le informazioni online, è possibile trovare tra le principali strategie popolari il cosiddetto trunk stabile e trunk instabile , ciascuno con un impatto opposto sulla frequenza delle fusioni. Vedete, le persone scelgono l'uno o l'altro modo di fare le cose senza nemmeno prestare attenzione alla centralizzazione di VCS.

  • Ho visto avvenire fusioni fortemente ritardate (anche incoraggiate dalla gestione degli zoppi) con VCS centralizzato, nonché frequenti fusioni effettuate con DVCS quando il team / management pensava che fosse la strada giusta. Ho visto che a nessuno importa se VCS è distribuito o centralizzato nel decidere in un modo o nell'altro.

Dato sopra, sembra la risposta giusta a DVCS che scoraggia l'integrazione continua? sarebbe Mu .

VCS distribuito o meno non ha un impatto sostanziale su questo.


1
+1 Sono d'accordo con te sul fatto che la gestione è la chiave per risolvere il problema. Tuttavia, dobbiamo ammettere che c'è qualcosa nel DVCS che scoraggia l'integrazione continua. In effetti, una delle caratteristiche chiave di DCVS incoraggia tale comportamento.

1
@ Pierre303 forse - anche io in qualche modo mi sento così, ma è praticamente una teoria. Come ho scritto, ho visto il team integrarsi come un matto con DVCS e, d'altra parte, il progetto più "isolazionista" in cui abbia mai lavorato (ed è stato un incubo) era con VCS centralizzato. Tanto per i sentimenti, tanto per la teoria ...
moscerino del

Devo ammettere che si tratta solo di un'osservazione empirica, ma su un gran numero di progetti, e probabilmente vi è un'enorme distorsione da "abilità".

10

La mia esperienza è esattamente l'opposto , i team che usano svn non farebbero push per giorni, perché il codice su cui stavano lavorando farebbe sì che il trunk non si compilasse per tutti gli altri senza perdere tempo a fondersi manualmente. Quindi, verso la fine dello sprint, tutti si impegnerebbero, si fonderebbe la follia, le cose verrebbero sovrascritte e perse e dovrebbero essere recuperate. Il sistema CI diventerebbe ROSSO e ne conseguirebbe il puntamento del dito.

Non ho mai avuto questo problema con Git / Gitorious.

Git ti consente di estrarre e unire i cambiamenti di altre persone a tuo piacimento, non perché qualcun altro ha effettuato il check-in e desideri effettuare il check-in, ma hai 20 minuti di fusione manuale da fare.

Git ti consente anche di eseguire il commit di tutti gli altri, unire il tuo codice e quindi inviare una versione funzionante a tutti gli altri in modo che non debbano indovinare cosa dovrebbero unire in base a ciò che hai cambiato.

Avere qualcosa come Gitorious come mediatore per le revisioni del codice tramite richieste di unione rende la gestione di molte filiali e di molti collaboratori molto indolore.

Anche l'impostazione di Jenkins / Hudson per tenere traccia di tutti i rami attivi in ​​un repository Git è molto semplice. Abbiamo ottenuto maggiore trazione con CI e feedback più frequenti sullo stato dei repository quando ci siamo trasferiti su Git da SVN.


perché dovrebbero impegnarsi direttamente nel trunk? Penso che questo sia stato il tuo problema.
gbjbaanb,

1
@gbjbaanb perché questo è il tradizionale modo di lavorare CVS idiomatico, perché questo è il tradizionale linguaggio centralizzato repo centralizzato. Gli utenti SVN sono in genere ex utenti CVS e la ramificazione e l'unione in SVN è solo leggermente migliore rispetto a CVS; che era oltre doloroso / quasi impossibile da correggere. Questo è il caso del 99% del flusso di lavoro nel 99% di tutti i negozi SVN a causa degli strumenti e del pensiero del gruppo.

@JarrodRoberson: sciocchezze. I miei vecchi utenti SVN erano rifugiati da VSS :) L'unione in SVN non è poi così grave come pensi. In questo caso, si lamenta che i suoi utenti avrebbero infranto la build controllando il codice non funzionante direttamente nel trunk - e quindi dover unire, francamente, dover unire il codice con quello del collega non è una cosa facoltativa se si sta lavorando direttamente lo stesso ramo.
gbjbaanb,

4

I server di build sono economici. Chiedi al tuo server CI di raccogliere tutti i rami che conosci.

Jenkins ha il supporto per controllare più repository git e ottenere il "più recente" da uno di quelli in un singolo lavoro. Sono sicuro che ci sono soluzioni simili con altri strumenti.


E cosa succede se vuoi impegnarti in qualcosa che si rompe headma aiuta un collega o è necessario affinché un collega possa aiutarti? Potresti creare un diff e inviarlo via e-mail al tuo collega, ma in qualche modo non ti sembra giusto.
Arjan,

1
Ramo di team / funzioni? O il pull diretto dal tuo repository di colleghi? Se più di una persona sta lavorando a qualcosa che potrebbe spezzare la testa ma richiede ancora un timeline / commit in più fasi, merita comunque la sua caratteristica / ramo di lavoro. Unisciti alla testa quando è pronto.
ptyx,

Un ramo di squadra del ramo di funzionalità non funzionerà se il tuo strumento CI raccoglie tutti i rami di cui sei a conoscenza. E se il tuo strumento CI elabora anche più repository, non vuoi ancora includere repository per sviluppatori, solo perché potrebbero non essere stati completamente testati.
Arjan,

1
Il server CI non verrà automaticamente a conoscenza di una filiale privata fino a quando non viene informato. Spetta agli individui scegliere se vogliono o meno i loro rami su CI. (Non esiste una soluzione miracolosa)
ptyx

Quindi CI non dovrebbe raccogliere tutti i rami che conosci, ma solo quelli che desideri in CI. Per me questa è una differenza. Tuttavia, penso di aver capito cosa stai cercando di dire, quindi +1
Arjan,

4

Questa vecchia domanda è stata appena contrassegnata come duplicata di una nuova e, poiché molte risposte fanno riferimento ad idee obsolete, ho pensato di pubblicarne una aggiornata.

Una cosa che apparentemente non era molto comune cinque anni fa era l'esecuzione di test CI su rami di richieste pull prima di fonderli in master. Penso che ciò rifletta un atteggiamento mutevole che, sebbene sia auspicabile una fusione frequente, condividere ogni cambiamento con tutti , non appena lo si effettua , non è ottimale.

DVCS ha generato una modalità più gerarchica di integrazione dei tuoi commit. Ad esempio, lavoro spesso a stretto contatto con lo sviluppatore che si trova accanto a me. Ci allontaneremo dai rami degli altri più volte al giorno. Oggi abbiamo collaborato con un altro sviluppatore tramite modifiche inviate a una richiesta pull ogni poche ore.

Stavamo apportando ampie modifiche agli script di build. Jenkins unisce localmente ogni filiale PR con master ed esegue i test, quindi abbiamo ottenuto un feedback automatico in quel modo, senza disturbare nessun altro sviluppatore che avesse bisogno di una build pulita. Probabilmente ci vorrà un altro giorno prima che PR sia pronta a fondersi per padroneggiare e condividere al di fuori del nostro gruppo di tre sviluppatori.

Tuttavia, se qualcuno non può aspettare che le nostre modifiche si uniscano al master, perché il loro cambiamento dipende dal nostro, può unire il nostro ramo di sviluppo localmente e continuare con il loro lavoro. Questo è ciò che manca a molte persone che sono abituate al CVCS. Con CVCS, l' unico modo per condividere le modifiche è fonderle nel repository centrale, ed è per questo che la fusione spesso è più critica. Con DVCS hai altre opzioni.


3

Direi che il DVCS è più favorevole all'integrazione continua. Le fusioni non sono così irritanti con loro. Richiede tuttavia più disciplina. È necessario seguire un commit locale con un pull dalla base per unire e quindi eseguire il push al termine dell'attività (prima di passare al successivo).


2

Quando il mio team è passato a Git, abbiamo esplicitamente definito il nostro processo in modo tale che una spinta dovesse essere trattata esattamente come un commit nel VCS più vecchio e che gli commit locali potevano essere eseguiti con la stessa frequenza / rarità di ogni individuo. Con ciò, non vi è alcuna differenza nel sistema CI se stiamo usando un DVCS o un VCS centralizzato.


1

La risposta è sia sì che no.

La differenza qui è tra il commit diretto al repository visualizzato con CI centrale e il trasferimento delle modifiche al repository visualizzato con CI centrale. Il "problema" che potresti trovare è che gli utenti DVCS potrebbero effettivamente non eseguire tale push regolarmente.

Direi che questa è una caratteristica di progettazione intrinseca di un DVCS, non è progettata per inviare continuamente le tue modifiche al server centrale - se così fosse, potresti usare un CVCS. Quindi la risposta è di applicare un flusso di lavoro migliore tra i tuoi sviluppatori. Di 'loro di spingere i cambiamenti ogni notte. Semplici!

(e se i tuoi utenti SVN non si impegnano ogni notte, diglielo - è lo stesso identico problema).


0

Git non impedisce l'integrazione continua. Il flusso di lavoro basato su trunk è.

Ciò può sembrare controintuitivo, ma: se gli sviluppatori lavorano sui rami delle funzionalità, possono essere incoraggiati a integrarsi frequentemente sui propri computer (e devono farlo prima di inviare le loro funzioni per unirle). Al contrario, un flusso di lavoro basato su trunk favorisce commit più grandi e quindi un'integrazione meno frequente.

Ritengo che un flusso di lavoro basato su trunk in stile Google sia controproducente con un VCS come Git in cui la fusione è facile. Ecco cosa consiglierei invece:

  • Abbatti le funzionalità abbastanza piccole che nessuno impiegherà più di un giorno o due per svilupparsi.
  • Ogni funzione è sviluppata su una filiale privata.
  • Lo sviluppatore si integra frequentemente nella filiale privata ( git fetch origin; git merge master). In genere lo faccio molte volte al giorno quando lavoro in questo modo.
  • Quando lo sviluppatore invia il ramo per unire e rivedere, il server CI esegue una generazione automatizzata. L'unione avviene solo quando passa.

Quindi il gioco è fatto: piccoli commit, integrazione frequente e una cronologia tracciabile di ciò che apparteneva a quale caratteristica. I rami, usati correttamente, sono la chiave di tutto ciò che vale Git, quindi evitarli è un grosso errore.


-1

Ci sono fantastiche soluzioni tecniche come @jdunay menzionate, ma per noi è un problema di persone - allo stesso modo che promuovere un ambiente in cui le persone si impegnano a svn è spesso un problema di persone.

Quello che ha funzionato per noi è: (sostituisci 'master' con il ramo di sviluppo attualmente attivo)

  1. Frequenti fusioni / rinunce dal master
  2. Spinte abbastanza frequenti da padroneggiare
  3. La consapevolezza delle cose che causano si fondono all'inferno, come alcuni rifattorizzazioni, e la mitigano comunicando. Per esempio:

    • Assicurati che tutti spingano prima di pranzo
    • Eseguire e spingere il refactoring durante il pranzo
    • Assicurati che tutti tirino dopo pranzo
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.