Come gestire i file duplicati nel controllo di versione

2

In questo momento usiamo un sistema molto semplice per il controllo della versione. Abbiamo un repository principale completamente piatto per la nostra intera linea di prodotti. Man mano che il nostro codebase cresce e aggiungiamo altri prodotti alla linea di prodotti, questo inizia a presentare alcuni seri inconvenienti. Ci piacerebbe allontanarci da questo, specialmente con uno stile piatto, ma ci sono problemi apparentemente fondamentali con un approccio strutturato, quindi sarebbe bello sapere come le altre persone gestiscono queste situazioni comuni:

  1. Il tuo codice ha più file duplicati in posizioni separate. Ad esempio, hai:

    ./somedir/source1.c
    ./someotherdir/source1.c
    

Tutte le istanze di source1.c sono uguali, quindi quando qualcuno cambia source1.c , non dovrebbero dover apportare la stessa modifica a ogni source1.c in ogni posizione in cui esiste. Questo è il tipo in cui funziona un sistema piatto, ma indica la struttura (con somedir e someotherdir devono essere creati per creare la struttura file corretta.

  1. D'altra parte, se hai qualcosa di simile:

    ./somedir/config
    ./someotherdir/config
    

dove entrambe le istanze di configurazione sono uniche e condividono solo un nome file. Questo presenta un grosso problema in un sistema piatto, si finisce per fare qualcosa come tenerli in un repository piatto con nomi univoci e quindi rinominarli mentre si ricrea la struttura del prodotto. Sembra che sia qui che un file system strutturato renderebbe le cose più semplici, perché non ci sarebbe alcuna relazione intrinseca tra ./somedir/config e ./someotherdir/config .

Forse mi sto avvicinando a questo con un'idea fondamentalmente errata degli idiomi standard, ma come sono sicuro che tutti voi sapete, quando state apportando grandi cambiamenti a una base di codice esistente, deve essere più una transizione che un lancio -questa situazione-via-e-inizio-inizio.

    
posta prelic 26.07.2014 - 19:33
fonte

2 risposte

2

La mia esperienza è con CVS e successivamente Subversion, quindi qualcun altro dovrà occuparsi dei sistemi distribuiti più moderni come Git e Mecurial.

La tua prima domanda (source.c) è probabilmente risolta meglio inserendo il codice comune nelle librerie, quindi collegando le librerie a più prodotti. In questo modo c'è solo un singolo file sorgente da modificare. SVN fornisce una funzione che farà apparire un file in più punti nell'albero dei sorgenti, ma se si prevede di portare l'integrazione continua e la compilazione / rilascio automatici nell'immagine, gli accoppiamenti incrociati diventano difficili da comprendere e da gestire. Preferisco di gran lunga l'approccio alla biblioteca.

La domanda sulla configurazione non è un problema. Per quanto ne so, tutti i sistemi di controllo del codice sorgente utilizzano il percorso completo per identificare il file, quindi i tuoi due file sono sicuramente archiviati in posti diversi.

    
risposta data 27.07.2014 - 01:50
fonte
2

Ci sono approcci all'interno di svn (e un altro approccio ). Altri strumenti come git gestiranno un link simbolico (e ulteriori informazioni ). È abbastanza comune che vari sistemi di controllo delle versioni abbiano un modo per gestire collegamenti simbolici ( perforce , hg come altri due).

A questo punto diventa una questione di come vuoi strutturare il tuo codice.

Tutto ciò che ho detto, all'inizio dirò che fare collegamenti simbolici o simili è spesso la risposta errata . Mentre hai ancora una singola copia del file che è la fonte di tutto, è troppo facile manipolare il link (qualcuno copia una versione precedente del file su di esso) e rendere infelice la giornata di qualcuno in futuro.

Hai un file oggetto di qualche tipo. Piuttosto che copiare il sorgente ( o heaven forbid #include "../foo/bar.c dimentica che l'ho scritto. Basta dimenticarlo per il tuo bene. Non lo hai visto.) Link al file oggetto.

Hai .../common/source1.c e questo produce .../common/source1.o e quando fai il link, è qualcosa come cc foo.o bar.o qux.o ${PROJECT_ROOT}/common/source1.o e tu sei bravo. Non copiare source1.c nella directory con foo, bar e qux perché non ne hai bisogno: ci sono modi migliori e più eleganti per gestirlo.

Se ti trovi in un mondo Java, fai in modo che i programmi di utilità o i servizi comuni (o qualsiasi altra cosa tu lo chiami) siano un progetto separato e lascia che sia una dipendenza di quelli che ne hanno bisogno. Simile per Go, o Python o altri linguaggi con uno strumento di creazione di gestione delle dipendenze.

Quindi - mantieni i file unici unici. La copia di file in più posizioni viola ASCIUGA e alla fine tornerà a morderti. I link simbolici sono migliori, ma devi essere disciplinato per usarli e non rovinarli con i file reali. Collega le librerie comuni quando è necessario - ma sono il loro progetto (se sono un progetto appropriato).

    
risposta data 27.07.2014 - 02:44
fonte

Leggi altre domande sui tag