Domanda

Nella mia azienda stiamo usando un repository SVN per contenere il nostro codice C ++. La base di codice è composta da una parte comune (infrastruttura e applicazioni) e progetti client (sviluppati come plugin).

Il layout del repository è simile al seguente:

  • Infrastrutture
  • App1
  • App2
  • App3
  • progetto-per-client-1
    • App1-plugin
    • App2-plugin
    • Configurazione
  • progetto-per-client-2
    • App1-plugin
    • App2-plugin
    • Configurazione

Una versione tipica di un progetto client include i dati del progetto e tutti i progetti utilizzati (ad es. Infrastruttura).

Il layout effettivo di ogni directory è -

  • Infrastruttura
    • rami
    • tronco
  • progetto-per-client-2
    • rami
    • tronco

E lo stesso vale per il resto dei progetti.

Abbiamo diversi problemi con il layout sopra:

  1. È difficile avviare un nuovo ambiente di sviluppo per un progetto client, dal momento che è necessario verificare tutti i progetti coinvolti (ad esempio: Infrastruttura, App1, App2, progetto per cliente-1).
  2. È difficile taggare una versione in un progetto client, per lo stesso motivo di cui sopra.
  3. Nel caso in cui un progetto client debba modificare un codice comune (ad es. Infrastruttura), a volte utilizziamo una filiale. È difficile tenere traccia delle filiali utilizzate nei progetti.

Esiste un modo in SVN per risolvere uno dei precedenti? Ho pensato di usare svn: externals nei progetti client, ma dopo aver letto questo post Capisco che potrebbe non essere la scelta giusta.

È stato utile?

Soluzione

Puoi gestirlo con svn: externals. Questo è l'URL di un punto in un repository svn Ciò consente di inserire parti di un repository diverso (o lo stesso). Un modo per usarlo è in project-for-client2, aggiungi un collegamento svn: externals al ramo dell'infrastruttura di cui hai bisogno, il ramo dell'app1 di cui hai bisogno, ecc. Quindi quando controlli project-for-client2, ottieni tutti i pezzi corretti.

I collegamenti svn: externals sono sottoposti a versione insieme a tutto il resto, quindi quando project-for-client1 viene taggato, ramificato e aggiornato, vengono sempre inseriti i rami esterni corretti.

Altri suggerimenti

Un suggerimento è quello di cambiare il layout della directory da

  • Infrastruttura
    • rami
    • tronco
  • progetto-per-client-1
    • rami
    • tronco
  • progetto-per-client-2
    • rami
    • tronco

a

  • rami
    • feature-1
      • Infrastrutture
      • progetto-per-client-1
      • progetto-per-client-2
  • tronco
    • Infrastrutture
    • progetto-per-client-1
    • progetto-per-client-2

Ci sono alcuni problemi anche con questo layout. I rami diventano enormi, ma almeno è più facile taggare luoghi specifici nel tuo codice.

Per lavorare con il codice, si dovrebbe semplicemente controllare il trunk e lavorare con quello. Quindi non hai bisogno degli script che controllano tutti i diversi progetti. Si riferiscono solo a Infrastruttura con " ../ Infrastruttura " ;. Un altro problema con questo layout è che è necessario effettuare il checkout di più copie se si desidera lavorare su progetti in modo completamente indipendente. In caso contrario, una modifica dell'infrastruttura per un progetto potrebbe impedire la compilazione di un altro progetto fino a quando non viene aggiornato.

Questo potrebbe rendere le pubblicazioni un po 'più ingombranti e separare il codice per diversi progetti.

Sì, fa schifo. Facciamo la stessa cosa, ma non riesco davvero a pensare a un layout migliore.

Quindi, ciò che abbiamo è un insieme di script in grado di automatizzare tutto ciò che riguarda la sovversione. Il progetto di ogni cliente conterrà un file chiamato project.list , che contiene tutti i progetti / percorsi di sovversione necessari per costruire quel cliente. Ad esempio:

Infrastructure/trunk
LibraryA/trunk
LibraryB/branches/foo
CustomerC/trunk

Ogni script ha quindi un aspetto simile al seguente:

for PROJ in $(cat project.list); do
    # execute commands here
done

Dove i comandi potrebbero essere un checkout, un aggiornamento o un tag. È un po 'più complicato di così, ma significa che tutto è coerente, il check-out, l'aggiornamento e la codifica diventano un singolo comando.

E ovviamente, proviamo a ramificarci il meno possibile, che è il suggerimento più importante che posso eventualmente fare. Se abbiamo bisogno di diramare qualcosa, proveremo a lavorare fuori dal trunk o dalla versione precedentemente taggata di quante più dipendenze possibili.

Innanzitutto, non sono d'accordo sul fatto che gli esterni siano malvagi. Sebbene non siano perfetti.

Al momento stai effettuando più checkout per creare una copia funzionante. Se utilizzassi gli esterni, farebbe esattamente questo, ma automaticamente e in modo coerente ogni volta.

Se punti i tuoi esterni verso tag (eo revisioni specifiche) all'interno dei progetti target, devi solo taggare il progetto corrente per release (dato che quel tag indicherebbe esattamente quale esterno stavi puntando). Avresti anche un record all'interno del tuo progetto esattamente quando hai cambiato i riferimenti esterni per utilizzare una nuova versione di una particolare libreria.

Gli esterni non sono una panacea e, come mostra il post, possono esserci problemi. Sono sicuro che c'è qualcosa di meglio degli esterni, ma non l'ho ancora trovato (nemmeno concettualmente). Certamente, la struttura che stai usando può produrre una grande quantità di informazioni e controllo nel tuo processo di sviluppo, l'uso di esterni può aggiungere a questo. Tuttavia, i problemi che aveva non erano problemi di corruzione fondamentali: una soluzione pulita risolverebbe tutto e sono piuttosto rari (non sei davvero in grado di creare un nuovo ramo di una libreria nel tuo repository?).

Punti da considerare: utilizzo di esterni ricorsivi. Non sono venduto né sul sì né sul no e tendo ad adottare un approccio pragmatico.

Prendi in considerazione l'uso del pistone come suggerisce l'articolo, non l'ho visto in azione, quindi non posso davvero commentare, potrebbe fare lo stesso lavoro degli esterni in un modo migliore.

Dalla mia esperienza, penso che sia più utile avere un repository per ogni singolo progetto. Altrimenti hai i problemi che dici e, inoltre, i numeri di revisione cambiano se cambiano altri progetti che potrebbero creare confusione.

Solo quando esiste una relazione tra singoli progetti, come software, schemi hardware, documentazione, ecc. Usiamo un singolo repository in modo che il numero di revisione serva a portare l'intero pacchetto in uno stato noto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top