Mal di testa che utilizzano il controllo della versione distribuita per i team tradizionali?


20

Anche se utilizzo DVCS e mi piacciono i miei progetti personali, e posso vedere totalmente come rendere più semplice la gestione dei contributi al tuo progetto da parte di altri (ad es. Il tuo tipico scenario Github), sembra che per un team "tradizionale" potrebbero esserci dei problemi nel approccio centralizzato impiegato da soluzioni come TFS, Perforce, ecc. (Per "tradizionale" intendo un team di sviluppatori in un ufficio che lavora su un progetto che nessuno "possiede", con potenzialmente tutti che toccano lo stesso codice.)

Un paio di questi problemi l'ho previsto da solo, ma per favore chime con altre considerazioni.

In un sistema tradizionale, quando si tenta di verificare la modifica al server, se qualcun altro ha precedentemente effettuato il check-in in una modifica in conflitto, si è costretti a unire prima di poter effettuare il check-in. Nel modello DVCS, ogni sviluppatore controlla il proprio cambia localmente e ad un certo punto passa ad altri repository. Quel repository ha quindi un ramo di quel file che 2 persone hanno cambiato. Sembra che ora qualcuno debba essere incaricato di affrontare quella situazione. Una persona designata nel team potrebbe non avere una conoscenza sufficiente dell'intera base di codice per essere in grado di gestire l'unione di tutti i conflitti. Quindi ora è stato aggiunto un ulteriore passaggio in cui qualcuno deve avvicinarsi a uno di quegli sviluppatori, dirgli di tirare e fare l'unione e poi spingere di nuovo (o devi costruire un'infrastruttura che automatizzi quel compito).

Inoltre, poiché DVCS tende a rendere il lavoro a livello locale così conveniente, è probabile che gli sviluppatori possano accumulare alcune modifiche nei loro repository locali prima di spingere, rendendo tali conflitti più comuni e più complicati.

Ovviamente se tutti i membri del team lavorano solo su diverse aree del codice, questo non è un problema. Ma sono curioso del caso in cui tutti stiano lavorando allo stesso codice. Sembra che il modello centralizzato imponga che i conflitti vengano affrontati rapidamente e frequentemente, riducendo al minimo la necessità di effettuare fusioni grandi e dolorose o di far "poliziare" il repository principale a chiunque.

Quindi, per quelli di voi che usano un DVCS con il proprio team nel proprio ufficio, come gestiscono tali casi? Ritieni che il tuo flusso di lavoro giornaliero (o più probabile, settimanale) sia influenzato negativamente? Ci sono altre considerazioni di cui dovrei essere a conoscenza prima di raccomandare un DVCS sul mio posto di lavoro?


Questa è un'ottima domanda. Il modo in cui hai descritto il problema è praticamente il motivo principale (tra gli altri) per cui non considero l'utilizzo di DVCS con il mio team (fortunatamente - o no - sono in grado di effettuare tale chiamata).
Alex,

Le mie esperienze e sentimenti sono molto simili alle tue.
William Payne,

Risposte:


26

Usiamo Mercurial da circa un anno. Mentre il mal di testa che menzioni esiste, di gran lunga, la più grande sfida alla piena adozione per noi era entrare nella mentalità DVCS dei repository locali (= commettere spesso.) La vecchia mentalità di "Commit dopo aver lucidato il codice" può essere difficile da lasciare partire.

Tu hai detto:

Nel modello DVCS, ogni sviluppatore controlla le proprie modifiche localmente e ad un certo punto passa ad altri repository. Quel repository ha quindi un ramo di quel file che 2 persone hanno cambiato. Sembra che ora qualcuno debba essere incaricato di affrontare quella situazione.

Un'installazione predefinita di Mercurial blocca questo comportamento. Non consentirà una spinta se nel repository remoto verrà creata più di una testa, senza ulteriore conferma. Per le attività quotidiane, lo evitiamo. (Git ha chiamato head e ognuno può essere aggiornato solo se unisce completamente la versione precedente, senza ulteriore conferma, quindi di nuovo la situazione non può sorgere. Anche gli altri DVCS hanno una protezione simile.)

Quindi alla fine di ogni giornata lavorativa, è necessario dedicare un po 'di tempo per l'impegno, che è proprio queste attività:

  1. Effettua modifiche locali.
  2. Estrarre dal repository centrale.
  3. Unisci (e commetti unione).
  4. Spingere nel repository centrale.

Ciò mantiene l'attività di unione su una persona che stava lavorando di recente su questo codice e dovrebbe essere in grado di integrare le proprie modifiche più rapidamente di chiunque altro.

Come sottolineato nella domanda, ciò aggiunge uno sforzo solo quando due persone lavorano sulla stessa area di codice. In tal caso, ci sono comunque maggiori vantaggi nell'uso del DVCS, quindi il profitto è già evidente per quegli sviluppatori. (Ulteriori vantaggi includono che ogni sviluppatore è in grado di eseguire il commit del codice separatamente e di giocare con il proprio repository senza che un altro sviluppatore si frapponga.)

Un altro problema che menzioni:

Inoltre, poiché DVCS tende a rendere il lavoro a livello locale così conveniente, è probabile che gli sviluppatori possano accumulare alcune modifiche nei loro repository locali prima di spingere, rendendo tali conflitti più comuni e più complicati.

Questo non crea un problema di unione per noi, ma potrebbe creare un problema diverso:

La flessibilità di DVCS significa che sono possibili molti flussi di lavoro diversi, ma alcuni di questi sono irresponsabili. Con DVCS, aumenta la necessità di processi o procedure chiari. L'attività di mantenimento dei cambiamenti locali può essere o non essere appropriata, a seconda di molte cose.

Ad esempio: uno sviluppatore può lavorare su una funzione per animali domestici nel tempo libero per alcune settimane? In alcuni ambienti questo è incoraggiato, in alcuni sarebbe inappropriato e tutti i cambiamenti dovrebbero essere centralizzati presto. Ma se uno sviluppatore mantiene le modifiche localmente, allora vorrà sicuramente attuare qualsiasi modifica correlata per assicurarsi che il suo lavoro continui a giocare bene con gli ultimi rev.

Quando la gomma incontra la strada, le versioni o le distribuzioni del software di solito provengono da un repository centrale, quindi gli sviluppatori devono apportare le loro modifiche per i test e la distribuzione.

Questa è la mia storia, e la seguo, per almeno un paio di minuti ...


Questo è abbastanza buono. La ramificazione può anche aggiungere una certa complessità alla situazione.
Paul Nathan,

4
Con DVCS, aumenta la necessità di processi o procedure chiari. da un grande potere derivano grandi responsabilità.
Newtopian,

5

La premessa della tua domanda sembra essere "Le fusioni sono difficili e devono essere evitate". I sistemi DVCS rimuovono questa barriera, in effetti fanno di più, abbracciano l'idea della fusione: non dovresti avere paura delle fusioni e unire i conflitti di conseguenza, poiché a differenza degli strumenti centralizzati, gli strumenti DVCS lo supportano in base alla progettazione.

Come afferma l'eccellente risposta di Jamie F: il flusso di lavoro di Commit-Pull-Merge-Push eseguito regolarmente (quotidianamente) significa che se stai camminando su alcuni lavori di altri, lo vedi presto - finché è visibile, può essere gestito .

I problemi che descrivi riguardano soprattutto il modo in cui scegli di utilizzare gli strumenti.

Siamo passati da SVN a GIT 6 mesi fa, dopo aver utilizzato SVN e GIT localmente per un paio di anni. Nessuno tornerà indietro e i dolorosi conflitti di fusione appartengono al passato. Il mantra "Commit piccolo e spesso" è la chiave.


3

Quando lavoravo in una squadra che utilizzava git, la regola empirica era questa: lavorare in una filiale privata, quindi, quando sei pronto a rendere il tuo lavoro disponibile per il resto della squadra, trasforma il tuo ramo in master prima di spingere. (Quindi convalida la tua filiale.)

Questa strategia significava che il master era una serie lineare di commit e che tutti i problemi di integrazione venivano riparati sulle filiali prima che fossero pubblici.


Rebasing "cambia la storia" e può essere un po 'più pericoloso. Se il rebase va male, non si ha più un registro di come apparivano i cambiamenti prima del rebase. Per questo motivo, molti sviluppatori sostengono che è necessario unire invece. Perdi le belle linee rette, ma ottieni la possibilità di riprovare una fusione andata storta. Inoltre, se non si esegue alcuna modifica fino a quando non è stato fatto tutto, non si sta proteggendo da crash del disco rigido o altri disastri locali. Ma sono sicuro che questo approccio funziona ancora per molte persone: probabilmente molto meglio di un VCS centralizzato.
StriplingWarrior

3

Uno strumento come SVN incoraggia fortemente un modo di lavorare strettamente integrato.

Vale a dire che si impegna frequentemente in un ramo condiviso (tronco o ramo dev).

Questo è A-OK per la maggior parte degli ambienti di sviluppo aziendale che ho sperimentato, ed è facilitato e incoraggiato ulteriormente attraverso l'uso di Integrazione continua supportata da test di integrazione, test di regressione e test unitari (Aiutare i singoli sviluppatori a ottenere la fiducia che non hanno rotto qualsiasi cosa dai loro cambiamenti).

DVCS ti dà la libertà di lavorare in modo più indipendente, cosa di cui hai bisogno in alcune situazioni, e il supporto (tanto decantato) migliorato per le fusioni non può fare alcun danno.

La preoccupazione che rimane sempre nella parte posteriore della mia mente è questa: con grande libertà arriva la tentazione di usare quella libertà.

Certamente, nella mia (limitata) esperienza, trascorro molto più tempo a lavorare in modo indipendente nel mio attuale team (usando Mercurial) rispetto a quanto avessi fatto in ruoli precedenti (dove abbiamo usato SVN, CVS e P4).

Questo è solo in parte attribuibile allo strumento, ma penso che sia ragionevole osservare che, in assenza di una ragione convincente per dedicare gli sforzi alla comunicazione e al coordinamento, le persone tenderanno a lavorare separatamente e in isolamento.

Questa non è necessariamente una cosa negativa, ma credo che sia qualcosa che deve essere preso in considerazione.


1

La cosa con il controllo della versione di tipo git / mercurial è impegnarsi spesso e passare al server centralizzato quando il codice è buono. Un grande vantaggio di questo è che crea piccole patch, che sono facili da applicare in caso di conflitti. Inoltre, il flusso di lavoro dovrebbe essere qualcosa nelle seguenti linee:

  1. Molti impegni locali
  2. Estrai dal server
  3. Invia al server

Questo pull dal server potrebbe creare conflitti, ma per risolverlo, tutto ciò che serve molte volte è un semplice rebase, anziché una fusione. Credo che ciò manterrà la storia della mainline piuttosto pulita e rimuoverà molti conflitti.

Questo è anche il caso quando si estrae dal repository locale di un collega, poiché potrebbero accadere due cose. O spinge prima sul server, il che va bene dato che hai già le sue patch e non dovrebbero verificarsi conflitti, oppure premi prima, il che significa che otterrà le tue patch solo quando tirerà.

Naturalmente, a volte un'unione è una soluzione migliore, ad esempio se si lavora su un ramo di funzionalità che dovrebbe essere unito in master.

Nel tuo flusso di lavoro stai parlando di persone che devono esplicitamente andare a un altro sviluppatore e dirgli di risolvere il conflitto, ma ciò non dovrebbe essere necessario. Il server centrale è il "capo" e ciò su cui dovresti principalmente lavorare. Se le modifiche si applicano al repository centrale, allora ok. In caso contrario, è il TUO compito risolvere il conflitto, il che potrebbe richiedere allo sviluppatore con cui sei in conflitto di aiutare a comprendere le sue modifiche. Questo è qualcosa che vedi quando tenti di estrarre / rebase dal server. Quindi sii felice di impegnarti e gestisci i conflitti quando dovresti ritirarti dal server.


0

Il principio di lavorare con un repository centralizzato è lo stesso quando si lavora con un sistema centralizzato o distribuito senza blocco:

  • Nel sistema centralizzato tu:
    1. Ottieni l'ultima versione da mainline ("trunk" in sovversione, "master" in git, ...)
    2. Modifica i file
    3. Unisci le modifiche con l'ultima versione dalla linea principale usando il comando "aggiorna"
    4. Impegnarsi a continuare
  • Nel sistema distribuito tu:
    1. Ottieni l'ultima versione da mainline
    2. Modifica i file
    3. Impegnare localmente
    4. Unisci le modifiche con l'ultima versione dalla linea principale e impegna il risultato localmente
    5. Premere sulla linea principale.

Nessuna versione distribuita ti consentirà di spingere la revisione che non unisce completamente la precedente revisione della testa (senza override speciale; a volte è utile), quindi non passerà senza fare il passaggio di unione (quindi non ci saranno due versioni qualcuno dovrebbe consolidarsi come ti interessa).

Ora notare che quattro dei passaggi sono gli stessi, tranne per la terminologia, ma i sistemi distribuiti aggiungono un ulteriore passaggio "3. Commit localmente". Il grande vantaggio di questo passaggio è che quando l'aggiornamento / pull crea conflitti e non sei sicuro di come risolverli o fare un errore risolvendoli, puoi tornare indietro, rivedere ciò che hai fatto e ripetere l'unione. Subversion non ricorderà nessuno di questi, quindi se si commette un errore nella risoluzione dell'aggiornamento, si è fregati.

Per quanto riguarda l'accumulo di cambiamenti, le persone tendono a farlo anche con un sistema centralizzato. Soprattutto se devi passare spesso da una funzionalità all'altra (come interrompere alcuni lavori più lunghi per correggere un bug o apportare alcune modifiche di cui il cliente ha urgente bisogno), le persone dovranno spesso mantenere le modifiche localmente semplicemente perché non sono finite. Quindi è meglio se il sistema almeno supporta il senso di esso.

In entrambi i casi, questi problemi devono essere affrontati da linee guida e comunicazioni adeguate nel team e non dagli strumenti. Con strumenti più flessibili le linee guida sono più importanti, ma gli strumenti più flessibili consentono di affrontare meglio vari casi angolari.

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.