Come migrare un repository SVN con cronologia in un nuovo repository Git?


1509

Ho letto il manuale di Git, le FAQ, il corso di crash Git - SVN, ecc. E tutti spiegano questo e quello, ma da nessuna parte puoi trovare una semplice istruzione come:

Repository SVN in: svn://myserver/path/to/svn/repos

Git repository in: git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

Non mi aspetto che sia così semplice, e non mi aspetto che sia un singolo comando. Ma mi aspetto che non provi a spiegare nulla, solo per dire quali passi fare in questo esempio.


6
Sta diventando più facile, l'ho appena completato da solo e ho documentato le mie scoperte con l'aiuto di SO jmoses.co/2014/03/21/moving-from-svn-to-git.html
John Moses,

Usa la risposta di Casey qui sotto, ma prima di eseguire il comando "svn clone ...", vedi come aggiungere la riga "Visual SVN Server" aggiuntiva al tuo file user.txt ... qui: stackoverflow.com/questions/8971208/ ...
MacGyver,

1
Inoltre, se hai l'opzione "Rendi privata la posta elettronica selezionata nel tuo profilo GitHub, usa questa come tuo indirizzo email in users.txt per abbinarla. Yourgituser@users.noreply.github.com, in modo che il tuo vero indirizzo email non venga visualizzato su commit
MacGyver

Risposte:


529

Magia:

$ git svn clone http://svn/repo/here/trunk

Git e SVN funzionano in modo molto diverso. Devi imparare Git e se vuoi tenere traccia delle modifiche da SVN a monte, devi imparare git-svn. La git-svn pagina principale ha una buona sezione di esempi :

$ git svn --help

140
La risposta di @Casey risponde molto meglio alla domanda originale.
Doug Wilson,

3
Ciò manterrà i rami e tutto il resto? o semplicemente clonare il tronco?
Eildosa,

7
@Eildosa: questo clonerà il tronco. Vedi la risposta di Casey per un'alternativa.
sleske,

3
@DougWilson ma non riesco a vedere nessuna risposta di Casey qui. È la risposta di seguito con 13 autori che inizia con "Crea un file utente"?
Andrey Regentov,

68
Per chiunque si stia chiedendo quale sia la "risposta di Casey" a cui fa riferimento un sacco di commenti qui intorno, è questo (Casey ha cambiato il suo nick in cmcginty).
Stefan Monov,

1560

Creare un file degli utenti (ovvero users.txt) per mappare gli utenti SVN su Git:

user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...

Puoi utilizzare questo one-liner per creare un modello dal tuo repository SVN esistente:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

SVN si interrompe se trova un utente SVN mancante non presente nel file. Ma dopo puoi aggiornare il file e riprendere da dove eri rimasto.

Ora estrae i dati SVN dal repository:

git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

Questo comando creerà un nuovo repository Git dest_dir-tmpe inizierà a estrarre il repository SVN. Nota che il flag "--stdlayout" implica che hai il layout comune "trunk /, branch /, tags /" SVN. Se il vostro è diverso layout, familiarizzare con --tags, --branches, --trunkopzioni (in generalegit svn help ).

Tutti i protocolli comuni sono consentiti: svn://, http://, https://. L'URL deve essere indirizzato al repository di base, ad esempio http://svn.mycompany.com/myrepo/repository . La stringa URL non deve includere /trunk, /tago/branches .

Si noti che dopo aver eseguito questo comando sembra molto spesso che l'operazione sia "bloccata / congelata" ed è abbastanza normale che possa essere bloccato a lungo dopo l'inizializzazione del nuovo repository. Alla fine vedrai i messaggi di registro che indicano che sta migrando.

Nota anche che se ometti il --no-metadataflag, Git aggiungerà al messaggio di commit informazioni sulla revisione SVN corrispondente (esgit-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID> )

Se non viene trovato un nome utente, aggiornare il users.txtfile quindi:

cd dest_dir-tmp
git svn fetch

Potrebbe essere necessario ripetere l'ultimo comando più volte, se si dispone di un progetto di grandi dimensioni, fino a quando tutti i commit di Subversion non sono stati recuperati:

git svn fetch

Al termine, Git eseguirà il checkout dell'SVN trunkin un nuovo ramo. Tutti gli altri rami sono configurati come telecomandi. Puoi visualizzare le altre filiali SVN con:

git branch -r

Se si desidera mantenere altri rami remoti nel proprio repository, si desidera creare un ramo locale per ognuno manualmente. (Salta trunk / master.) Se non lo fai, i rami non verranno clonati nel passaggio finale.

git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same name

I tag vengono importati come rami. Devi creare un ramo locale, creare un tag ed eliminare il ramo per averli come tag in Git. Per farlo con il tag "v1":

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

Clona il tuo repository GIT-SVN in un repository Git pulito:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

I rami locali creati in precedenza da rami remoti saranno stati copiati solo come rami remoti nel nuovo repository clonato. (Salta trunk / master.) Per ogni ramo che si desidera mantenere:

git checkout -b local_branch origin/remote_branch

Infine, rimuovi il telecomando dal tuo repository Git pulito che punta al repository temporaneo ora cancellato:

git remote rm origin

36
Questo post sul blog di Eelke è un ottimo riferimento incrociato per la risposta sopra. blokspeed.net/blog/2010/09/converting-from-subversion-to-git
kgriffs

4
Questo è fantastico al 99%, seguendo questi passaggi, ho ottenuto tutto in ordine tranne i rami: dopo l'ultimo passaggio, erano solo remoti (e come tali sono scomparsi quando ho fatto il comando: git remote rm origin)
Dirty Henry

4
GitHub ha un passaggio molto conveniente: github.com/nirvdrum/svn2git#readme
Dan Nissenbaum,

8
Per quelli con Windows, ho creato uno script PowerShell basato su questo metodo: gist.github.com/Gimly/90df046dc38181bb18de
Gimly

5
Avviso per grandi repository con molta storia, questo è lento e noioso . Ho rinunciato a cercare di migrare tutti i vecchi rami e semplicemente il tronco migrato.
Jess,

195

Migrare in modo pulito il repository Subversion in un repository Git . Per prima cosa devi creare un file che associ i nomi degli autori del commit di Subversion ai commit Git, ad esempio ~/authors.txt:

jmaddox = Jon Maddox <jon@gmail.com>
bigpappa = Brian Biggs <bigpappa@gmail.com>

Quindi è possibile scaricare i dati di Subversion in un repository Git:

mkdir repo && cd repo
git svn init http://subversion/repo --no-metadata
git config svn.authorsfile ~/authors.txt
git svn fetch

Se sei su un Mac, puoi ottenere git-svnda MacPorts installando git-core +svn.

Se il repository subversion si trova sullo stesso computer del repository git desiderato, è possibile utilizzare questa sintassi per il passaggio init, altrimenti lo stesso:

git svn init file:///home/user/repoName --no-metadata

1
Come ho commentato l'altra risposta, ho dovuto togliere gli spazi intorno =in users.txtquanto l'importazione è stata abortire e mi è stato sempre un repository vuoto.
Sebastián Grignoli,

8
Ah! Spiegazione semplice ed efficace. Nel mio caso mi sono file:///rifiutato di funzionare, solo che ho usato svnserve.exe --daemone poi usato svn://localhost/home/user/repoinvece.
Daniel Reis,

Sul mio Mac con Mountain Lion, git svn non funzionerebbe fino a quando non sono entrato in Xcode e non ho installato gli strumenti da riga di comando che si trovano nella scheda Download del pannello Preferenze. In alternativa, avrei potuto installare solo gli strumenti da riga di comando per OS X Mountain Lion presenti sul sito per sviluppatori di Apple.
Estratto il

3
Per il mio caso ho dovuto convertire il file authors.txtin utf-8 without BOM.
Silvan,

Questo ha funzionato alla grande per me! Una volta che avevo il repository locale, ho usato il post di cmcginty a partire da "Clona il tuo repository GIT-SVN in un repository Git pulito:" Penso che il motivo principale per cui mi è piaciuta la risposta di @zoul sia stato l'uso git svn init, git svn configquindi alla fine git svn fetchè stato più facile per farlo in questo modo, ho dovuto recuperare più volte per farlo bene. La linea singola di cmcginty git svn clone, che fa tutte e tre le cose, era troppo confusa per me.
Mike

70

Ho usato lo script svn2git e funziona come un incantesimo.


4
D: questo risolve gli spazi nei nomi di tag e branch (consentiti in svn e non consentiti in git)?
spazm



È preferibile spiegare le risposte, altrimenti si producono script kiddie.
Josh Habdas,

Che dire se i tuoi rami sono tutti nella radice di SVN e non hai trunk o tag?
Kal,

58

Suggerisco di familiarizzare con Git prima di provare a usare git-svn costantemente, ovvero mantenendo SVN come repository centralizzato e usando Git localmente.

Tuttavia, per una semplice migrazione con tutta la cronologia, ecco alcuni semplici passaggi:

Inizializza il repository locale:

mkdir project
cd project
git svn init http://svn.url

Contrassegna da quanto tempo vuoi iniziare a importare le revisioni:

git svn fetch -r42

(o semplicemente "git svn fetch" per tutti i giri)

Recupera tutto da allora:

git svn rebase

Puoi controllare il risultato dell'importazione con Gitk. Non sono sicuro che funzioni su Windows, su OSX e Linux:

gitk

Quando hai il tuo repository SVN clonato localmente, potresti voler spingerlo in un repository Git centralizzato per una più facile collaborazione.

Per prima cosa crea il tuo repository remoto vuoto (forse su GitHub ?):

git remote add origin git@github.com:user/project-name.git

Quindi, facoltativamente, sincronizza il tuo ramo principale in modo che l'operazione pull unisca automaticamente il master remoto con il tuo master locale, quando entrambi contengono nuovi elementi:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

Successivamente, potresti essere interessato a provare il mio git_remote_branch strumento personale, che aiuta a gestire filiali remote:

Primo post esplicativo: " Git filiali remote "

Seguito dato alla versione più recente: "È ora di collaborare con git_remote_branch "


Estremamente utile, ha funzionato perfettamente. Vorrei aggiungere che c'è un ultimo passo da compiere se si sta eseguendo la sincronizzazione con un repository remoto. Dopo i passaggi di configurazione git, dovevogit push origin master
mag382

31

Esiste una nuova soluzione per una migrazione senza problemi da Subversion a Git (o per usarli entrambi contemporaneamente): SubGit .

Sto lavorando a questo progetto da solo. Usiamo SubGit nei nostri repository - alcuni dei miei compagni di squadra usano Git e alcuni Subversion e finora funziona molto bene.

Per migrare da Subversion a Git con SubGit devi eseguire:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

Dopodiché otterrai il repository Git in svn_repos / .git e potresti clonarlo, o semplicemente continuare a usare Subversion e questo nuovo repository Git insieme: SubGit farà in modo che entrambi siano sempre sincronizzati.

Nel caso in cui il repository Subversion contenga più progetti, verranno creati più repository Git nella directory svn_repos / git. Per personalizzare la traduzione prima di eseguirla, procedi come segue:

$ subgit configure svn_repos
$ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc)
$ subgit install svn_repos

Con SubGit puoi migrare a Git puro (non git-svn) e iniziare a usarlo mantenendo comunque Subversion finché ne hai bisogno (per i tuoi strumenti di build già configurati, per esempio).

Spero che sia di aiuto!


4
Si noti che un'importazione singola (utilizzando il subgit importcomando) non sembra nemmeno richiedere una licenza. È inclusa anche la traduzione accurata della svn:ignoreproprietà in .gitignorefile.
krlmlr

1
SubGit non riconoscerebbe la mia chiave privata, né alcun flag impostato nella riga di comando. La documentazione è molto scarsa. Questa non è una valida alternativa per git svn.
pfnuesel,

1
errore: 'svn_repos' non è un percorso configurato valido; File di configurazione SubGit mancante.
Jon Davis,

19

Vedi la manpage ufficiale di git-svn . In particolare, guarda in "Esempi di base":

Tracciamento e contributo a un intero progetto gestito da Subversion (completo di trunk, tag e rami):

# Clone a repo (like git clone):
    git svn clone http://svn.foo.org/project -T trunk -b branches -t tags

Il tuo comando clone ha funzionato, quelli sopra non mi hanno dato altro che repository git vuoti. L'unica differenza sembra essere l'esplicito '-T trunk'.
user1984717


14

SubGit (vs Blue Screen of Death)

subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

È tutto.

+ Per aggiornare da SVN, un repository Git creato dal primo comando.

subgit import  directory/path/Local.git.Repo

Ho usato un modo per migrare su Git all'istante per un enorme repository.
Naturalmente hai bisogno di un po 'di preparazione.
Ma potresti non interrompere affatto il processo di sviluppo.

Ecco la mia strada

La mia soluzione è simile a:

  • Migrare SVN in un repository Git
  • Aggiorna il repository Git poco prima di passare al team .

La migrazione richiede molto tempo per un grande repository SVN.
Ma l'aggiornamento della migrazione completata in pochi secondi.

Certo che sto usando SubGit , mamma. git-svn mi rende Blue Screen of Death . Solo costantemente. E git-svn mi annoia con l' errore fatale " nome file troppo lungo " di Git .

PASSI

1. Scarica SubGit

2. Preparare i comandi di migrazione e aggiornamento.

Diciamo che lo facciamo per Windows (è banale eseguire il port su Linux).
Nella directory bin di installazione di un SubGit (subgit-2.XX \ bin), creare due file .bat.

Contenuto di un file / comando per la migrazione:

start    subgit import --svn-url url://svn.serv/Bla/Bla  directory/path/Local.git.Repo

Il comando "start" è facoltativo qui (Windows). Permetterà di vedere gli errori all'avvio e di lasciare aperta una shell dopo il completamento di SubGit.

È possibile aggiungere qui parametri aggiuntivi simili a git-svn . Sto usando solo --default-domain myCompanyDomain.com per correggere il dominio dell'indirizzo email degli autori SVN.
Ho la struttura standard del repository SVN (trunk / rami / tag) e non abbiamo avuto problemi con la "mappatura degli autori". Quindi non sto più facendo niente.

(Se vuoi migrare tag come branch o il tuo SVN ha più cartelle branch / tags che potresti prendere in considerazione per usare l' approccio SubGit più dettagliato )

Suggerimento 1 : Usa --minimal-revision YourSvnRevNumber per vedere velocemente come vanno le cose (una specie di debug). Particolarmente utile è vedere i nomi degli autori risolti o le e-mail.
O per limitare la profondità della cronologia delle migrazioni.

Suggerimento 2 : la migrazione potrebbe essere interrotta ( Ctrl+ C) e ripristinata eseguendo il comando / file di aggiornamento successivo.
Non consiglio di farlo per grandi repository. Ho ricevuto "Eccezione memoria Java + Windows esaurita".

Suggerimento 3 : Meglio creare una copia del repository nudo dei risultati.

Contenuto di un file / comando per l'aggiornamento:

start    subgit import  directory/path/Local.git.Repo

Puoi eseguirlo tutte le volte che vuoi ottenere gli ultimi commit della squadra nel tuo repository Git.

Avvertimento! Non toccare il tuo repository nudo (creazione di rami ad esempio).
Prenderai il prossimo errore fatale:

Errore irreversibile: non sono sincronizzati e non possono essere sincronizzati ... La traduzione delle revisioni di Subversion in Git impegna ...

3. Esegui il primo comando / file. Ci vorrà molto tempo per un grande repository. 30 ore per il mio umile repository.

È tutto.
Puoi aggiornare il tuo repository Git da SVN in qualsiasi momento in qualsiasi momento eseguendo il secondo file / comando. E prima di passare il tuo team di sviluppo a Git.
Ci vorranno solo pochi secondi.



C'è un altro compito utile.

Sposta il tuo repository Git locale in un repository Git remoto

È il tuo caso? Procediamo

  1. Configura i tuoi telecomandi

Correre:

$ git remote add origin url://your/repo.git
  1. Preparati all'invio iniziale del tuo enorme repository Git locale a un repository remoto

Di default il tuo Git non può inviare grossi pezzi. fatale: l'estremità remota ha riattaccato inaspettatamente

Corriamo per questo:

git config --global http.postBuffer 1073741824

524288000-500 MB 1073741824-1 GB, ecc.

Risolvi i problemi del certificato locale . Se il tuo server git utilizza un certificato non funzionante.

Ho disabilitato i certificati .

Inoltre, il tuo server Git potrebbe avere delle limitazioni sull'importo della richiesta che devono essere corrette .

  1. Invia tutta la migrazione al repository Git remoto del team.

Esegui con un Git locale:

git push origin --mirror

( git push origin '*: *' per le vecchie versioni di Git)

Se ricevi quanto segue: errore: impossibile generare git: nessun file o directory simile ... Per me la ricreazione completa del mio repository risolve questo errore (30 ore). Puoi provare i comandi successivi

git push origin --all
git push origin --tags

Oppure prova a reinstallare Git ( inutile per me ). Oppure puoi creare rami da tutti i tuoi tag e spingerli. Oppure, o, o ...


10

reposurgeon

Per casi complicati, il repository di Eric S. Raymond è lo strumento preferito. Oltre a SVN, supporta molti altri sistemi di controllo della versione tramite il fast-exportformato e CVS . L'autore riporta conversioni di successo di antichi repository come Emacs e FreeBSD .

Apparentemente lo strumento mira a una conversione pressoché perfetta (come convertire le svn:ignoreproprietà di SVN in .gitignorefile) anche per layout di repository difficili con una lunga storia. In molti casi, altri strumenti potrebbero essere più facili da usare.

Prima di approfondire la documentazione della reposurgeonriga di comando, assicurati di leggere l'eccellente guida alla migrazione DVCS che esamina passo per passo il processo di conversione.



8

Devi installare

git
git-svn

Copiato da questo link http://john.albin.net/git/convert-subversion-to-git .

1. Recupera un elenco di tutti i committer Subversion

Subversion elenca semplicemente il nome utente per ogni commit. I commit di Git hanno dati molto più ricchi, ma nella sua semplicità, l'autore del commit deve avere un nome e un indirizzo e-mail elencati. Per impostazione predefinita, lo strumento git-svn elencherà semplicemente il nome utente SVN sia nei campi dell'autore che dell'email. Ma con un po 'di lavoro, puoi creare un elenco di tutti gli utenti SVN e quali sono il loro nome Git ed e-mail corrispondenti. Questo elenco può essere usato da git-svn per trasformare semplici nomi utente svn in committer Git appropriati.

Dalla radice del checkout Subversion locale, esegui questo comando:

svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

Ciò catturerà tutti i messaggi di registro, eliminerà i nomi utente, eliminerà qualsiasi nome utente duplicato, ordinerà i nomi utente e li inserirà in un file "autori-transform.txt". Ora modifica ogni riga nel file. Ad esempio, converti:

jwilkins = jwilkins <jwilkins>

in questo:

jwilkins = John Albin Wilkins <johnalbin@example.com>

2. Clonare il repository Subversion usando git-svn

git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

Questo eseguirà la trasformazione standard git-svn (usando il file autori-transform.txt che hai creato nel passaggio 1) e posizionerà il repository git nella cartella “~ / temp” all'interno della tua home directory.

3. Converti svn: ignora le proprietà in .gitignore

Se il tuo repository svn utilizzava le proprietà svn: ignore, puoi facilmente convertirlo in un file .gitignore usando:

cd ~/temp
git svn show-ignore > .gitignore
git add .gitignore
git commit -m 'Convert svn:ignore properties to .gitignore.'

4. Push repository in un repository bare git

Innanzitutto, crea un repository nudo e fai in modo che il suo ramo predefinito corrisponda al nome del ramo "trunk" di svn.

git init --bare ~/new-bare.git
cd ~/new-bare.git
git symbolic-ref HEAD refs/heads/trunk

Quindi spingere il repository temporaneo nel nuovo repository nudo.

cd ~/temp
git remote add bare ~/new-bare.git
git config remote.bare.push 'refs/remotes/*:refs/heads/*'
git push bare

Ora puoi eliminare in sicurezza il repository ~ / temp.

5. Rinomina il ramo "trunk" in "master"

Il tuo ramo di sviluppo principale sarà chiamato "trunk" che corrisponde al nome che era in Subversion. Ti consigliamo di rinominarlo nel ramo "master" standard di Git usando:

cd ~/new-bare.git
git branch -m trunk master

6. Pulisci rami e tag

git-svn trasforma tutti i tag Subversions in rami molto corti in Git del formato "tag / nome". Ti consigliamo di convertire tutti quei rami in tag Git effettivi usando:

cd ~/new-bare.git
git for-each-ref --format='%(refname)' refs/heads/tags |
cut -d / -f 4 |
while read ref
do
  git tag "$ref" "refs/heads/tags/$ref";
  git branch -D "tags/$ref";
done

Questo passaggio richiederà un po 'di digitazione. :-) Ma non preoccuparti; la shell unix fornirà un> prompt secondario per il comando extra-lungo che inizia con git for-each-ref.


7

GitHub ora ha una funzione da importare da un repository SVN . Non l'ho mai provato, però.


3
L' attuale raccomandazione di GitHub è quella di utilizzare il svn2gitprogramma suggerito in un'altra risposta .
ntc2,

Importati due progetti piuttosto grandi proprio ora impeccabilmente. Tutti i rami SVN sono stati importati (ricorda di NON utilizzare la parte \ trunk nel percorso repository). Una cosa che non so ancora è che se Github avrebbe tracciato nuovi commit.
Fr0sT

7

Una risposta in qualche modo estesa usando solo git, SVN e bash. Include passaggi per i repository SVN che non utilizzano il layout convenzionale con un layout di directory trunk / branch / tags (SVN non fa assolutamente nulla per imporre questo tipo di layout).

Per prima cosa usa questo script bash per scansionare il tuo repository SVN per le diverse persone che hanno contribuito e per generare un modello per un file di mapping:

#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
  echo "${author} = NAME <USER@DOMAIN>";
done

Utilizzalo per creare un authorsfile in cui mappare nomi utente svn su nomi utente ed e-mail come impostato dai tuoi sviluppatori utilizzando le git configproprietà user.namee user.email(tieni presente che per un servizio come GitHub che ha solo un'e-mail corrispondente è sufficiente).

Quindi git svnclonare il repository svn in un repository git, informandolo sulla mappatura:

git svn clone --authors-file=authors --stdlayout svn://example.org/Folder/projectroot

Questo può richiedere molto tempo, dal momento che git svn verificherà individualmente ogni revisione per ogni tag o ramo esistente. (nota che i tag in SVN sono solo rami, quindi finiscono come tali in Git). Puoi accelerarlo rimuovendo tag e rami vecchi in SVN che non ti servono.

Eseguirlo su un server nella stessa rete o sullo stesso server può anche velocizzarlo. Inoltre, se per qualche motivo questo processo viene interrotto, puoi riprenderlo usando

git svn rebase --continue

In molti casi hai finito qui. Ma se il tuo repository SVN ha un layout non convenzionale in cui hai semplicemente una directory in SVN che vuoi inserire in un ramo git, puoi fare alcuni passaggi extra.

Il più semplice è semplicemente creare un nuovo repository SVN sul server che segua la convenzione e utilizzi svn copyper mettere la directory in trunk o in un ramo. Questo potrebbe essere l'unico modo se la tua directory è completamente alla radice del repository, quando l'ho provato l'ultima volta mi sono git svnsemplicemente rifiutato di fare un checkout.

Puoi anche farlo usando git. Per git svn cloneusare semplicemente la directory che vuoi inserire in un ramo git.

Dopo l'esecuzione

git branch --set-upstream master git-svn
git svn rebase

Si noti che ciò richiede Git 1.7 o versioni successive.


Proporrei di combinare queste informazioni con questo link: sailmaker.co.uk/blog/2013/05/05/…
Joan PS

7

Ho pubblicato una guida passo passo ( qui ) per convertire svn in git, inclusa la conversione di tag svn in tag git e rami svn in rami git.

Versione breve:

1) clonare svn da un numero di revisione specifico. (il numero di revisione deve essere il più vecchio che si desidera migrare)

git svn clone --username=yourSvnUsername -T trunk_subdir -t tags_subdir -b branches_subdir -r aRevisionNumber svn_url gitreponame

2) recupera i dati svn. Questo passaggio è quello che richiede più tempo.

cd gitreponame
git svn fetch

ripeti git svn fetch fino al termine senza errori

3) ottenere il ramo master aggiornato

git svn rebase

4) Creare rami locali da rami svn copiando i riferimenti

cp .git/refs/remotes/origin/* .git/refs/heads/

5) converti i tag svn in tag git

git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done

6) Metti un repository in un posto migliore come Github

git remotes add newrepo git@github.com:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo

Se vuoi maggiori dettagli, leggi il mio post o chiedimi.


6

Possiamo usare i git svn clonecomandi come di seguito.

  • svn log -q <SVN_URL> | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors.txt

Il comando sopra creerà il file degli autori dai commit SVN.

  • svn log --stop-on-copy <SVN_URL>

Il comando sopra ti darà il primo numero di revisione quando il tuo progetto SVN è stato creato.

  • git svn clone -r<SVN_REV_NO>:HEAD --no-minimize-url --stdlayout --no-metadata --authors-file authors.txt <SVN_URL>

Il comando sopra creerà il repository Git in locale.

Il problema è che non convertirà rami e tag in push. Dovrai farlo manualmente. Ad esempio di seguito per i rami:

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
* master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$$ git checkout -b MyDevBranch origin/MyDevBranch
Branch MyDevBranch set up to track remote branch MyDevBranch from origin.
Switched to a new branch 'MyDevBranch'
$ git branch -a
* MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$

Per i tag:

$git checkout origin/tags/MyDevBranch-1.0
Note: checking out 'origin/tags/MyDevBranch-1.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 3041d81... Creating a tag
$ git branch -a
* (detached from origin/tags/MyDevBranch-1.0)
  MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$ git tag -a MyDevBranch-1.0 -m "creating tag"
$git tag
MyDevBranch-1.0
$

Ora invia master, rami e tag al repository git remoto.

$ git push origin master MyDevBranch MyDevBranch-1.0
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (14/14), 2.28 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To https://github.com/pankaj0323/JDProjects.git
 * [new branch]      master -> master
 * [new branch]      MyDevBranch -> MyDevBranch
 * [new tag]         MyDevBranch-1.0 -> MyDevBranch-1.0
$

utilità svn2git

L' utilità svn2git rimuove gli sforzi manuali con rami e tag.

Installalo usando il comando sudo gem install svn2git. Dopo quello esegui sotto il comando.

  • $ svn2git <SVN_URL> --authors authors.txt --revision <SVN_REV_NO>

Ora puoi elencare i rami, i tag e spingerli facilmente.

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
  MyDevBranch
* master
  remotes/svn/MyDevBranch
  remotes/svn/trunk
$ git tag
  MyDevBranch-1.0
$ git push origin master MyDevBranch MyDevBranch-1.0

Immagina di avere 20 rami e tag, ovviamente svn2git ti farà risparmiare un sacco di tempo ed è per questo che mi piace meglio dei comandi nativi. È un bel wrapper per nativigit svn clone comando .

Per un esempio completo, fai riferimento al mio blog .




3

Se stai usando SourceTree puoi farlo direttamente dall'app. Vai a File -> Nuovo / Clone quindi procedi come segue:

  1. Immettere l'URL SVN remoto come "Percorso / URL di origine".
  2. Inserisci le tue credenziali quando richiesto.
  3. Immettere il percorso della cartella locale come "Percorso di destinazione".
  4. Dagli un nome.
  5. Nelle opzioni avanzate selezionare "Git" dal menu a discesa in "Crea repository locale di tipo".
  6. È possibile specificare facoltativamente una revisione da cui clonare.
  7. Hit Clone.

Apri il repository in SourceTree e vedrai che anche i tuoi messaggi di commit sono stati migrati.

Ora vai su Repository -> Impostazioni repository e aggiungi i dettagli del nuovo repository remoto. Se lo desideri, elimina il telecomando SVN (l'ho fatto tramite l'opzione "Modifica file di configurazione".

Invia il codice al nuovo repository remoto quando sei pronto e codifica liberamente.


Grazie, veloce e veloce!
Rikard,

Grazie. Questo ha funzionato per me. Sto usando SourceTree e Stash.
VK_217,

3

Per gli utenti di GitLab ho spiegato come sono migrato da SVN qui:

https://gist.github.com/leftclickben/322b7a3042cbe97ed2af

Passaggi per migrare da SVN a GitLab

Impostare

  • SVN è ospitato presso svn.domain.com.au.
  • SVN è accessibile tramite http(altri protocolli dovrebbero funzionare).
  • GitLab è ospitato su git.domain.com.aue:
    • Viene creato un gruppo con lo spazio dei nomi dev-team.
    • Almeno un account utente viene creato, aggiunto al gruppo e ha una chiave SSH per l'account utilizzato per la migrazione (test utilizzando ssh git@git.domain.com.au).
    • Il progetto favourite-projectviene creato nello dev-teamspazio dei nomi.
  • Il file users.txtcontiene i dettagli utente pertinenti, un utente per riga, del modulo username = First Last <address@domain.com.au>, dove usernameè il nome utente fornito nei registri SVN. (Per i dettagli, vedere il primo collegamento nella sezione Riferimenti, in particolare la risposta dell'utente Casey).

versioni

  • versione di sovversione 1.6.17 (r1128011)
  • versione git 1.9.1
  • GitLab versione 7.2.1 ff1633f
  • Server Ubuntu 14.04

comandi

bash
git svn clone --stdlayout --no-metadata -A users.txt 
http://svn.domain.com.au/svn/repository/favourite-project
cd favourite-project
git remote add gitlab git@git.domain.com.au:dev-team/favourite-project.git
git push --set-upstream gitlab master

Questo è tutto! Ricarica la pagina del progetto nell'interfaccia utente web di GitLab e vedrai tutti i commit e i file ora elencati.

Appunti

  • Se ci sono gli utenti sconosciuti, il git svn clonecomando si ferma, in tal caso, l'aggiornamento users.txt, cd favourite-projecte git svn fetchcontinuerà dal punto in cui si è fermato.
  • È richiesto il layout standard trunk- tags- branchesper il repository SVN.
  • Lo SVN URL dato al git svn clonecomando arresta al livello immediatamente superiore trunk/, tags/e branches/.
  • Il git svn clonecomando produce un sacco di output, inclusi alcuni avvisi in alto; Ho ignorato gli avvertimenti.

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia.
Blackhole,

1
Non sono d'accordo. Il contenuto collegato potrebbe cambiare e il contenuto duplicato qui non verrà aggiornato e pertanto potrebbe non essere aggiornato (e in effetti credo che sia cambiato da quando ho pubblicato originariamente questa risposta). Le linee guida dicono solo di includere un contesto pertinente per un collegamento, cosa che ho fatto - alla domanda reale è stata data una risposta all'ingrosso dal collegamento. Non è necessario o necessario copiare qui l'intera risorsa collegata. Sono stato sottoposto a downgrade per questo ?!
leftclickben,

2

Come altro a parte, il comando git-stash è una manna dal cielo quando si cerca di git con ditit git-svn.

Un processo tipico:

  1. configurare git repo
  2. fare un po 'di lavoro su file diversi
  3. decidere di controllare alcuni dei lavori, usando git
  4. decidere di svn-dcommit
  5. ottenere il temuto errore "impossibile eseguire il commit con un indice sporco".

La soluzione (richiede git 1.5.3+):

git stash; git svn dcommit ; git stash apply

2

Ecco un semplice script di shell senza dipendenze che convertirà uno o più repository SVN in git e li spingerà in GitHub.

https://gist.github.com/NathanSweet/7327535

In circa 30 righe di script esso: clona usando git SVN, crea un file .gitignore da SVN :: ignora le proprietà, inserisce un repository git nudo, rinomina il trunk SVN in master, converte i tag SVN in tag git e lo spinge in GitHub preservando i tag.

Ho sofferto molto per spostare una dozzina di repository SVN da Google Code a GitHub. Non mi è stato d'aiuto usare Windows. Ruby si era rotto in qualche modo sulla mia vecchia scatola Debian e farlo funzionare su Windows era uno scherzo. Altre soluzioni non hanno funzionato con i percorsi Cygwin. Anche una volta che ho fatto funzionare qualcosa, non sono riuscito a capire come far apparire i tag su GitHub (il segreto è --follow-tags).

Alla fine ho messo insieme due script brevi e semplici, collegati sopra, e funziona alla grande. La soluzione non deve essere più complicata di così!


2
Ho usato questo script. Dopo un po 'di tracce ed errori, ha funzionato per me. Si prega di notare che è necessario Git 1.8.3+ per questo, poiché --follow-tags è supportato solo in seguito.
nrobey,

2

Sono su una macchina Windows e ho fatto un piccolo batch per trasferire un repository SVN con cronologia (ma senza rami) in un repository GIT semplicemente chiamando

transfer.bat http://svn.my.address/svn/myrepo/trunk https://git.my.address/orga/myrepo

Forse chiunque può usarlo. Crea una cartella TMP che controlla il repository SVN lì con git e aggiunge la nuova origine e la spinge ... ed elimina di nuovo la cartella.

@echo off 
SET FROM=%1 
SET TO=%2 
SET TMP=tmp_%random%

echo from:  %FROM% 
echo to:    %TO% 
echo tmp:   %TMP%

pause

git svn clone  --no-metadata --authors-file=users.txt %FROM% %TMP%  
cd %TMP% 
git remote add origin %TO% 
git push --set-upstream origin master


cd .. 
echo delete %TMP% ... 
pause

rmdir /s /q %TMP%

Hai ancora bisogno di users.txt con i tuoi mapping utente come

User1 = User One <u.1@xxx.com>

Questa risposta mi ha aiutato a spostare senza problemi tutti i miei repository su BitBucket.
Gonzalingui,

Felice di sentire. Ho avuto solo esperienza con Gitea ... ma trasferito ~~ 40 repository in questo modo.
cljk,

Molto bella! Thnx
b3wii

avvertimento; Ho riscontrato problemi con i set di caratteri non validi. L'ho riconosciuto davvero troppo tardi, ma mi ci sono volute diverse ore per sistemare. Verifica che il repository risultante contenga le fonti esatte (!)
Previste

1

Volevo solo aggiungere il mio contributo alla comunità Git. Ho scritto un semplice script bash che automatizza l'importazione completa. A differenza di altri strumenti di migrazione, questo strumento si basa su git nativo anziché su jGit. Questo strumento supporta anche repository con una cronologia delle revisioni di grandi dimensioni o o BLOB di grandi dimensioni. È disponibile tramite github:

https://github.com/onepremise/SGMS

Questo script convertirà i progetti archiviati in SVN con il seguente formato:

/trunk
  /Project1
  /Project2
/branches
     /Project1
     /Project2
/tags
 /Project1
 /Project2

Questo schema è anche popolare e supportato:

/Project1
     /trunk
     /branches
     /tags
/Project2
     /trunk
     /branches
     /tags

Ogni progetto verrà sincronizzato dal nome del progetto:

Ex: ./migration https://svnurl.com/basepath project1

Se si desidera convertire l'intero repository, utilizzare la sintassi seguente:

Ex: ./migration https://svnurl.com/basepath .

0

L'uso efficace di Git con Subversion è una dolce introduzione a git-svn. Per i repository SVN esistenti, git-svn rende tutto ciò estremamente semplice. Se stai avviando un nuovo repository, è molto più semplice creare prima un repository SVN vuoto e quindi importarlo usando git-svn di quanto non vada nella direzione opposta. La creazione di un nuovo repository Git e l'importazione in SVN può essere eseguita, ma è un po 'doloroso, soprattutto se non conosci Git e speri di preservare la cronologia dei commit.


0

Scarica il programma di installazione di Ruby per Windows e installa l'ultima versione con esso. Aggiungi eseguibili Ruby al tuo percorso.

  • Installa svn2git
  • Menu Start -> Tutti i programmi -> Ruby -> Avvia un prompt dei comandi con Ruby
  • Quindi digitare "gem install svn2git" e inserire

    Migrare il repository Subversion

  • Apri un prompt dei comandi di Ruby e vai alla directory in cui i file devono essere migrati

    Quindi svn2git http: // [ nome dominio ] / svn / [repository root]

  • Potrebbero essere necessarie alcune ore per migrare il progetto su Git dipende dalle dimensioni del codice del progetto.

  • Questo passaggio importante aiuta a creare la struttura del repository Git come indicato di seguito.

    Tronco SVN (/ Project_components) -> rami Git master SVN (/ Project_components) -> rami Git tag SVN (/ Project_components) -> tag Git

Crea il repository remoto e invia le modifiche.


0

GitHub ha un importatore. Dopo aver creato il repository, è possibile importare da un repository esistente, tramite il suo URL. Chiederà le tue credenziali se applicabile e passerà da lì.

Mentre è in esecuzione, troverà gli autori e potrai semplicemente mapparli agli utenti su GitHub.

L'ho usato per alcuni repository ora, ed è abbastanza preciso e anche molto più veloce! Ci sono voluti 10 minuti per un repository con ~ 4000 commit, e dopo il mio amico ha impiegato quattro giorni!


0

Diverse risposte qui si riferiscono a https://github.com/nirvdrum/svn2git , ma per i repository di grandi dimensioni questo può essere lento. Ho provato a usare https://github.com/svn-all-fast-export/svn2git invece che è uno strumento con esattamente lo stesso nome ma è stato usato per migrare KDE da SVN a Git.

Un po 'più di lavoro per configurarlo, ma una volta eseguita la conversione stessa ho impiegato minuti in cui l'altro script ha trascorso ore.


0

Esistono diversi metodi per raggiungere questo obiettivo. Ne ho provati alcuni e ne ho trovato davvero uno funzionante con solo git e svn installati sul sistema operativo Windows.

Prerequisiti:

  1. git su windows (ho usato questo) https://git-scm.com/
  2. svn con gli strumenti della console installati (ho usato tartaruga svn)
  3. File di dump del repository SVN. svnadmin dump /path/to/repository > repo_name.svn_dump

Passaggi per raggiungere l'obiettivo finale (spostare tutto il repository con cronologia su un git, prima git locale, quindi remoto)

  1. Crea un repository vuoto (usando gli strumenti della console o tortoiseSVN) nella directory REPO_NAME_FOLDER cd REPO_NAME_PARENT_FOLDER, inserisci dumpfile.dump in REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Attendere questa operazione, potrebbe essere lungo

  3. Questo comando è silenzioso, quindi apri la seconda finestra cmd: svnserve -d -R --root REPO_NAME_FOLDER perché non usare semplicemente file: /// ......? Perché il prossimo comando fallirà Unable to open ... to URL:, grazie alla risposta https://stackoverflow.com/a/6300968/4953065

  4. Crea una nuova cartella SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn: // localhost / Attendi questa operazione.

Alla fine, cosa abbiamo?

Consente di controllare il nostro repository locale:

git log

Vedi i tuoi precedenti impegni? Se sì, va bene

Quindi ora hai un repository git locale completamente funzionale con le tue fonti e la vecchia storia di svn. Ora, se vuoi spostarlo su un server, usa i seguenti comandi:

git remote add origin https://fullurlpathtoyourrepo/reponame.git
git push -u origin --all # pushes up the repo and its refs for the first time
git push -u origin --tags # pushes up any tags

Nel mio caso, non ho bisogno del comando tags perché il mio repository non ha tag.

In bocca al lupo!


0

Conversione del sottomodulo / cartella svn 'MyModule' in git con cronologia senza tag né rami.

Per conservare svn ignora l'elenco utilizzare i commenti sopra dopo il passaggio 1

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.