2010-06-17 16 views
29

Abbiamo una grande base di codice che contiene diversi progetti condivisi, file di soluzione, ecc. In una directory in SVN. Stiamo migrando su Mercurial. Vorrei cogliere l'occasione per riorganizzare il nostro codice in diversi repository per fare in modo che la clonazione per le diramazioni abbia meno spese generali. Ho già convertito con successo il nostro repository da SVN a Mercurial preservando la storia. La mia domanda: come posso suddividere tutti i diversi progetti in repository separati preservando la loro storia?Dividi grande repository in più sottorepos e conserva la cronologia (Mercurial)

Ecco un esempio di quello che il nostro unico repository (OurPlatform) attualmente si presenta come:

/OurPlatform 
---- Core 
---- Core.Tests 
---- Database 
---- Database.Tests 
---- CMS 
---- CMS.Tests 
---- Product1.Domain 
---- Product1.Stresstester 
---- Product1.Web 
---- Product1.Web.Tests 
---- Product2.Domain 
---- Product2.Stresstester 
---- Product2.Web 
---- Product2.Web.Tests 
==== Product1.sln 
==== Product2.sln 

Tutte queste sono cartelle contenenti VS Progetti fatta eccezione per i file di soluzione. Product1.sln e Product2.sln fanno riferimento a tutti gli altri progetti. Idealmente, mi piacerebbe prendere ognuna di queste cartelle e trasformarle in repository Hg separati e aggiungere anche nuovi repository per ogni progetto (fungono da repository principali). Quindi, se qualcuno dovesse lavorare su Product1, clonerebbe il repository Product1, che conteneva i riferimenti Product1.sln e subrepo a ReferenceAssemblies, Core, Core.Tests, Database, Database.Tests, CMS e CMS.Tests.

Quindi, è facile farlo con hg initing nelle directory del progetto. Ma si può fare preservando la storia? O c'è un modo migliore per organizzare questo?

EDIT ::::

Grazie alla risposta di Ry4an, sono stato in grado di realizzare il mio obiettivo. Volevo condividere come l'ho fatto qui per gli altri.

Dato che avevamo molti progetti separati, ho scritto un piccolo script bash per automatizzare la creazione delle filemaps e creare lo script bat finale per eseguire effettivamente la conversione. Ciò che non era completamente chiaro dalla risposta, è che il comando convert deve essere eseguito una volta per ogni filemap, per produrre un repository separato per ogni progetto. Questo script verrebbe inserito nella directory sopra una copia di lavoro svn precedentemente convertita. Ho usato la copia di lavoro dal momento che la sua struttura di file corrispondeva meglio a ciò che volevo che il nuovo repository hg definitivo fosse.

#!/bin/bash 

# this requires you to be in: /path/to/svn/working/copy/, and issue: ../filemaplister.sh ./ 

for filename in * 
do 
    extension=${filename##*.} #$filename|awk -F . '{print $NF}' 
    if [ "$extension" == "sln" -o "$extension" == "suo" -o "$extension" == "vsmdi" ]; then 
    base=${filename%.*} 
    echo "#$base.filemap" >> "$base.filemap" 
    echo "include $filename" >> "$base.filemap" 
    echo "C:\Applications\TortoiseHgPortable\hg.exe convert --filemap $base.filemap ../hg-datesort-converted ../hg-separated/$base > $base.convert.output.txt" >> "MASTERGO.convert.bat" 
    else 
    echo "#$filename.filemap" >> "$filename.filemap" 
    echo "include $filename" >> "$filename.filemap" 
    echo "rename $filename ." >> "$filename.filemap" 
    echo "C:\Applications\TortoiseHgPortable\hg.exe convert --filemap $filename.filemap ../hg-datesort-converted ../hg-separated/$filename > $filename.convert.output.txt" >> "MASTERGO.convert.bat" 
    fi 
done; 

mv *.filemap ../hg-conversion-filemaps/ 
mv *.convert.bat ../hg-conversion-filemaps/ 

Questo script guarda tutti i file in una copia di lavoro svn, e in base al tipo o crea un nuovo file FileMap o aggiunge ad una già esistente. L'if è in realtà solo per catturare vari file di Visual Studio e metterli in un repository separato. Questo è pensato per essere eseguito su bash (cygwin nel mio caso), ma l'esecuzione del comando di conversione reale viene eseguita tramite la versione di hg fornita con TortoiseHg a causa di problemi di fork/processo su Windows (gah, lo so ...).

Quindi si esegue il file MASTERGO.convert.bat, che esamina il repository hg convertito e crea repository separati utilizzando la mappa dei filtri fornita. Una volta completato, c'è una cartella chiamata hg-separated che contiene una cartella/repository per ogni progetto, oltre a una cartella/repository per ogni soluzione. È quindi necessario clonare manualmente tutti i progetti in un repository di soluzioni e aggiungere i cloni al file .hgsub. Dopo aver eseguito il commit, viene creato un file .hgsubstate e tu sei pronto per partire!

Con l'esempio di cui sopra, il mio file .hgsub assomiglia a questo per "Product1":

Product1.Domain = /absolute/path/to/Product1.Domain 
Product1.Stresstester = /absolute/path/to/Product1.Stresstester 
Product1.Web = /absolute/path/to/Product1.Web 
Product1.Web.Tests = /absolute/path/to/Product1.Web.Tests 

volta a trasferire queste operazioni pronti contro termine a un server centrale, sarò cambiare manualmente i percorsi di essere gli URL .

Inoltre, non esiste un analogo al repository iniziale di OurPlatform svn, poiché ora tutto è separato.

Grazie ancora!

risposta

28

Questo può assolutamente essere fatto. Ti consigliamo di utilizzare il comando hg convert. Ecco il processo userei:

  1. convertire tutto a un unico repository hg utilizzando hg convert con un tipo di fonte di svn e un tipo di dest hg (sembra che tu hai già fatto questo passo)
  2. creare una collezione di filemap file da utilizzare con l'opzione --filemaphg convert s'
  3. corsa hg convert con il tipo di fonte hg e tipo dest hg e la fonte è il repo mercuriale creato nel passo uno - e farlo per ciascuno dei filemaps creati nel secondo passaggio.

La sintassi FileMap è mostrato nella hg help convert uscita, ma qui è il succo:

The filemap is a file that allows filtering and remapping of files and 
directories. Comment lines start with '#'. Each line can contain one of 
the following directives: 

    include path/to/file 

    exclude path/to/file 

    rename from/file to/file 

Quindi nel tuo esempio tuoi filemaps sarebbe simile a questa:

# this is Core.filemap 
include Core 
rename Core . 

Si noti che se si avere una inclusione che l'esclusione di tutto il resto è implicita. Anche quella linea di rinomina finisce in un punto e sposta tutto di un livello.

# this is Core.Tests 
include Core.Tests 
rename Core.Tests . 

e così via.

Dopo aver creato i repository interrotti per ciascuno dei nuovi repository, è possibile eliminare il repository iniziale has-everything creato nel passaggio uno e avviare l'impostazione della configurazione del subrepo nei file .hgsub.

+0

Grazie, questo è stato perfetto! – Andrew

+5

Se non funziona, ricorda che è necessario chiamare "hg update" sul nuovo repository per visualizzare i file. Ho perso questa parte ... – bsk

+0

È vero, il tuo nuovo repository ha la cronologia, ma non ottieni una copia nella directory di lavoro finché non si aggiorna "hg" –

Problemi correlati