Strategia per utilizzare il controllo della versione su un sistema modulare

15

Supponiamo (per semplicità) di avere un'applicazione con client e server; c'è un'idea migliore per utilizzare un repository per entrambi o una coppia di repository separati?

Mescolarli probabilmente renderà più facile tracciare i cambiamenti correlati e mantenere i rami correlati (ad es. evoluzione del protocollo), ma d'altra parte renderà lo sviluppo individuale più disordinato ...

    
posta mbq 20.12.2011 - 16:54
fonte

6 risposte

12

Se utilizzi git o mercuriale , quindi potresti voler consultare i sottomoduli o subrepositories .

Il client, il server ei relativi file di interfaccia si troverebbero nei propri repository, ma sarebbero collegati insieme a il livello super-repository . Questo ti permetterebbe di fare un checkout al livello più alto e git o hg controllerebbe il commit appropriato di ciascuno dei sottomoduli / sottosposizioni.

Usando solo il super-repository quando sia il client che il server erano appropriati l'uno con l'altro, il super-repository ti darebbe sempre la possibilità di controllare un sistema funzionante - così non proverai mai ad eseguire il nuovo client contro un vecchio server o viceversa.

I sottomoduli / sottopriposti offrono tutti i vantaggi dell'utilizzo di repository separati, insieme ai vantaggi di un singolo repository monolitico, a scapito di una piccola complessità extra.

Questa risposta non è intesa a sostenere git o hg rispetto ad altri SCM, è solo che so solo questi SCM abbastanza bene da sapere che questa opzione esiste . Non capisco come funziona svn esternal.

    
risposta data 20.12.2011 - 17:55
fonte
6

Separare!

In effetti, probabilmente ho tre repository, uno per il Client e le librerie solo client corrispondenti, uno per il Server (e le librerie corrispondenti) e uno per le librerie condivise (incorporando le interfacce API che espongono la funzionalità tra i due, più qualsiasi altro codice condiviso). Penso che sia davvero la chiave, il codice condiviso dovrebbe andare in un proprio repository separato. In questo modo puoi assicurarti che l'interoperabilità tra client e server sia sempre alla stessa versione E sia isolata dal design di ciascuno dei suoi consumatori.

Ovviamente, questo non è sempre possibile, a seconda del particolare framework di comunicazione che stai utilizzando, ma è probabile che ci sia un codice condiviso che determina il formato degli oggetti di trasferimento dati o le fasi di handshake nel tuo protocollo personalizzato (o alcuni altro esempio).

Supponendo di avere un'integrazione continua abbastanza buona e una configurazione di QA (una supposizione abbastanza ampia, secondo la mia esperienza, ma ne farò comunque uno.) Se non si dispone di un dipartimento di QA, si dovrebbe almeno ottenere un CI ) non dovresti aver bisogno di usare il pattern single-repo come difesa contro possibili mis-match di codice, il tuo server CI segnalerà l'interoperabilità della libreria o il tuo team di controllo qualità rileverà errori di runtime (o, ancora meglio, i tuoi test di unità) volontà).

I vantaggi dei repository separati risiedono nella possibilità di eseguire separatamente le parti separate di un sistema. Vuoi prendere una copia del server della scorsa settimana ed eseguirlo con il client di questa settimana, per cercare di bloccare la radice di un problema di prestazioni? Nessun problema.

    
risposta data 20.12.2011 - 18:04
fonte
1

In Mercurial , questo schema può essere utilizzato, utilizzando -> per indicare la relazione del subrepo:

product -> client -|-> (many components)
                   |->  shared component A

        -> server -|-> (many components)
                   |->  shared component A

Il prodotto ha subrepos client, server. Ognuno di questi ha i suoi componenti come sottorepos, forse almeno un sottorubrica condiviso tra i due.

Il tagging dovrebbe probabilmente essere fatto sui primi due livelli, non al di sotto di questo.

I commit sono fatti a livello di componente, i superrepos tracciano efficacemente i rami e le versioni nominati del prodotto. I rami / segnalibri nominati sono solitamente migliori dei rami cloni per usabilità (ossia la capacità di allenamento) e compatibilità con i sottorepos.

hg tende all'ipotesi che il superrepos sia il prodotto, e che i commit siano fatti al livello più alto, ma che non funzioni particolarmente bene quando più prodotti usano gli stessi componenti. : -)

Non penso che questo schema cambierà molto se passerai a git, ma non l'ho ancora provato in git.

    
risposta data 20.12.2011 - 19:43
fonte
1

Questo è un problema di gestione della configurazione, non un problema di controllo di revisione. Come sempre, un programmatore usa un cacciavite per martellare un chiodo. Scopri come gestirai le tue configurazioni, il controllo di revisione si prenderà cura di se stesso.

    
risposta data 21.12.2011 - 02:55
fonte
1

L'approccio più semplice è quello di utilizzare un singolo repository, quindi a meno che non ti piaccia la complessità per la complessità, allora quella dovrebbe essere la scelta predefinita in assenza di argomenti convincenti altrimenti.

Lo sviluppo di client e server verrà eseguito da diverse organizzazioni? Ci saranno più implementazioni del client (o del server)? Il client open source e l'implementazione del server sono segreti? Se la risposta a tutte queste domande è "No", qualsiasi cosa più complessa di un singolo repository può portare solo inconvenienti senza alcun beneficio.

Se scegli di mantenere codebase separati, avrai bisogno di politiche chiare su come questo viene amministrato, al fine di evitare incompatibilità e infernali dipendenze. Dopo aver lavorato con i primi singhiozzi, potresti scoprire che la cosa più sicura è sempre controllare insieme entrambi i repository, costruirli insieme e disporli insieme ... il che ovviamente sconfigge l'intero scopo di separarli!

La modularità è una proprietà piacevole da avere, ma suddividere i repository non è uno strumento per raggiungerlo. Come suggerisce il paragrafo precedente, puoi avere componenti altamente accoppiati che sono suddivisi su più codebase (indesiderabili), e allo stesso modo puoi avere componenti altamente modulari all'interno della stessa base di codice (desiderabile).

In più di un'occasione, ho sostenuto (con successo) che il mio team unisse repository git esistenti, perché ha semplificato lo sviluppo e la distribuzione.

    
risposta data 25.01.2015 - 07:48
fonte
0

Dimentica il repository per un momento. Come organizzeresti i due progetti sulla tua macchina se non condividessi con nessuno? Come lo farebbe il resto del team? Vuoi ...

  • Metti tutti i file sorgente sia per client che per server nella stessa directory?

  • Creare una directory di progetto principale che contenga sottodirectory per il client e il server?

  • Mantieni i due progetti completamente separati?

Una volta raggiunto un certo consenso su questo come gruppo, sei pronto per controllare i progetti nel tuo repository di codice. Tutti gli strumenti di controllo di revisione a cui posso pensare sono felici di riprodurre qualsiasi struttura di directory che ti piace - a loro non importa un po 'di quale file appartiene a quale progetto. E la differenza tra avere un repository o due (o sei) di solito non è così grande, a parte piccole differenze amministrative.

Ad esempio, con Subversion, la differenza maggiore tra repository separati per client e server e un singolo repository combinato è nel modo in cui i numeri di revisione cambiano. Con un repository singolo, il numero di versione aumenta ogni volta che si esegue il commit del codice su client o server. Con repository separati, un commit al progetto server non cambierà il numero di revisione principale per il client.

    
risposta data 20.12.2011 - 19:58
fonte

Leggi altre domande sui tag