Comment migrer un référentiel SVN avec historique vers un nouveau référentiel Git?

1510

J'ai lu le manuel Git, la FAQ, le cours accéléré Git - SVN, etc. et ils expliquent tous ceci et cela, mais nulle part vous ne pouvez trouver une instruction simple comme:

Référentiel SVN dans: svn://myserver/path/to/svn/repos

Référentiel Git dans: 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

Je ne m'attends pas à ce que ce soit aussi simple, et je ne m'attends pas à ce que ce soit une seule commande. Mais je m'attends à ce qu'il n'essaye pas d'expliquer quoi que ce soit - juste pour dire quelles mesures prendre compte tenu de cet exemple.

Milan Babuškov
la source
6
Cela devient plus facile, je viens de le terminer moi-même et j'ai documenté mes conclusions avec l'aide de SO jmoses.co/2014/03/21/moving-from-svn-to-git.html
John Moses
Utilisez la réponse de Casey ci-dessous, mais avant d'exécuter la commande "svn clone ...", voyez comment ajouter la ligne supplémentaire "Visual SVN Server" à votre fichier user.txt ... ici: stackoverflow.com/questions/8971208/ …
MacGyver
1
De plus, si vous avez coché l'option "Rendre le courrier électronique privé dans votre profil GitHub, utilisez-la comme adresse e-mail dans users.txt pour qu'elle corresponde. [email protected], afin que votre véritable adresse e-mail ne s'affiche pas sur les validations
MacGyver

Réponses:

529

La magie:

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

Git et SVN fonctionnent très différemment. Vous devez apprendre Git, et si vous voulez suivre les changements de SVN en amont, vous devez apprendre git-svn. La git-svn page principale contient une bonne section d'exemples :

$ git svn --help
jfm3
la source
140
La réponse de @Casey répond beaucoup mieux à la question d'origine.
Doug Wilson
3
Est-ce que cela gardera les branches et tout? ou simplement cloner le coffre?
Eildosa
7
@Eildosa: Cela ne fera que cloner le tronc. Voir la réponse de Casey pour une alternative.
sleske
3
@DougWilson mais je ne vois aucune réponse de Casey ici. Est-ce la réponse ci-dessous avec 13 auteurs qui commence par "Créer un fichier d'utilisateurs"?
Andrey Regentov
68
Pour tous ceux qui se demandent quelle est la "réponse de Casey" qui est référencée dans de nombreux commentaires ici, c'est celle-ci (Casey a changé son pseudo en cmcginty).
Stefan Monov
1560

Créez un fichier d'utilisateurs (c'est-à-dire users.txt) pour mapper les utilisateurs SVN à Git:

user1 = First Last Name <[email protected]>
user2 = First Last Name <[email protected]>
...

Vous pouvez utiliser ce one-liner pour créer un modèle à partir de votre référentiel SVN existant:

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

SVN s'arrêtera s'il trouve un utilisateur SVN manquant qui ne se trouve pas dans le fichier. Mais après cela, vous pouvez mettre à jour le fichier et reprendre là où vous vous étiez arrêté.

Maintenant, tirez les données SVN du référentiel:

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

Cette commande créera un nouveau référentiel Git dans dest_dir-tmpet commencera à extraire le référentiel SVN. Notez que le drapeau "--stdlayout" implique que vous avez la disposition SVN "trunk /, branches /, tags /" commune. Si votre diffère de mise en page, de se familiariser avec --tags, --branches, des --trunkoptions (en général git svn help).

Tous les protocoles communs sont autorisés: svn://, http://, https://. L'URL doit cibler le référentiel de base, quelque chose comme http://svn.mycompany.com/myrepo/repository . La chaîne URL ne doit pas inclure /trunk, /tagni /branches.

Notez qu'après avoir exécuté cette commande, il semble très souvent que l'opération est "suspendue / gelée", et il est tout à fait normal qu'elle puisse être bloquée pendant une longue période après l'initialisation du nouveau référentiel. Finalement, vous verrez alors des messages de journal qui indiquent qu'il migre.

Notez également que si vous omettez l' --no-metadataindicateur, Git ajoutera des informations sur la révision SVN correspondante au message de validation (c'est-à-dire git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>)

Si aucun nom d'utilisateur n'est trouvé, mettez à jour votre users.txtfichier puis:

cd dest_dir-tmp
git svn fetch

Vous devrez peut-être répéter cette dernière commande plusieurs fois, si vous avez un grand projet, jusqu'à ce que toutes les validations de Subversion aient été récupérées:

git svn fetch

Une fois terminé, Git va retirer le SVN trunkdans une nouvelle branche. Toutes les autres branches sont configurées comme télécommandes. Vous pouvez voir les autres branches SVN avec:

git branch -r

Si vous souhaitez conserver d'autres branches distantes dans votre référentiel, vous souhaitez créer manuellement une branche locale pour chacune. (Ignorer le tronc / maître.) Si vous ne le faites pas, les branches ne seront pas clonées à l'étape finale.

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

Les balises sont importées sous forme de branches. Vous devez créer une branche locale, créer une balise et supprimer la branche pour les avoir comme balises dans Git. Pour le faire avec la balise "v1":

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

Clonez votre référentiel GIT-SVN dans un référentiel Git propre:

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

Les branches locales que vous avez créées précédemment à partir de branches distantes n'ont été copiées qu'en tant que branches distantes dans le nouveau référentiel cloné. (Ignorer le tronc / maître.) Pour chaque branche que vous souhaitez conserver:

git checkout -b local_branch origin/remote_branch

Enfin, supprimez la télécommande de votre référentiel Git propre qui pointe vers le référentiel temporaire maintenant supprimé:

git remote rm origin
cmcginty
la source
36
Ce billet de blog par Eelke est une excellente référence croisée pour la réponse ci-dessus. blokspeed.net/blog/2010/09/converting-from-subversion-to-git
kgriffs
4
C'est génial à 99%, en suivant ces étapes, j'ai tout mis en ordre sauf les branches: après la dernière étape, elles étaient à distance uniquement (et en tant que telles ont disparu quand j'ai fait la commande: git remote rm origin)
Dirty Henry
4
GitHub a une étape par étape très pratique: github.com/nirvdrum/svn2git#readme
Dan Nissenbaum
8
Pour ceux sous Windows, j'ai créé un script PowerShell basé sur cette méthode: gist.github.com/Gimly/90df046dc38181bb18de
Gimly
5
Attention pour les grands repos avec beaucoup d'histoire, c'est lent et fastidieux . J'ai renoncé à migrer toutes les anciennes branches et j'ai simplement migré le tronc.
Jess
195

Migrez proprement votre référentiel Subversion vers un référentiel Git . Vous devez d'abord créer un fichier qui mappe les noms de vos auteurs de commit Subversion aux commiteurs Git, par exemple ~/authors.txt:

jmaddox = Jon Maddox <[email protected]>
bigpappa = Brian Biggs <[email protected]>

Ensuite, vous pouvez télécharger les données Subversion dans un référentiel Git:

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

Si vous êtes sur un Mac, vous pouvez obtenir git-svnde MacPorts en installant git-core +svn.

Si votre référentiel subversion est sur la même machine que votre référentiel git souhaité, vous pouvez utiliser cette syntaxe pour l'étape init, sinon tout de même:

git svn init file:///home/user/repoName --no-metadata
zoul
la source
1
Comme je l' ai commenté l'autre réponse, je devais enlever les espaces autour =de users.txtparce que l'importation a été avorte et je recevais un dépôt vide.
Sebastián Grignoli
8
Ah! Explication simple et efficace. Dans mon cas, j'ai file:///refusé de travailler, j'ai simplement utilisé svnserve.exe --daemonpuis utilisé à la svn://localhost/home/user/repoplace.
Daniel Reis
Sur mon Mac exécutant Mountain Lion, git svn ne fonctionnerait pas tant que je ne serais pas entré dans Xcode et installé les outils de ligne de commande trouvés dans l'onglet Téléchargements du volet Préférences. Sinon, j'aurais pu installer uniquement les outils de ligne de commande pour OS X Mountain Lion trouvés sur le site des développeurs d'Apple.
Drew
3
Pour mon cas, j'ai dû convertir le fichier authors.txten utf-8 without BOM.
Silvan
Cela a très bien fonctionné pour moi! Une fois que j'ai eu le référentiel local, j'ai utilisé le post de cmcginty commençant par "Cloner votre référentiel GIT-SVN dans un référentiel Git propre:" Je pense que la principale raison pour laquelle j'ai aimé la réponse de @zoul était l'utilisation de git svn init, git svn configpuis finalement git svn fetchcomme c'était plus facile pour le faire de cette façon, j'ai dû aller chercher plusieurs fois pour bien faire les choses. La ligne unique de cmcginty git svn clone, qui fait les trois, était trop confuse pour moi.
Mike
70

J'ai utilisé le script svn2git et fonctionne comme un charme.

Uwe Keim
la source
4
Q: cela corrige-t-il les espaces dans les noms de balises et de branches (autorisés dans svn et non autorisés dans git)?
spazm
2
Ce guide pour l'utiliser est utile: troyhunt.com/2014/08/migrating-from-subversion-to-git-with.html
Morten Holmgaard
Cela a échoué pour moi avec un problème: groups.google.com/forum/#!topic/msysgit/7MQVwRO-2N4 - voir aussi: github.com/nirvdrum/svn2git/issues/50 La solution était là: stackoverflow.com/questions / 3009738 /…
HDaoût
Il est préférable d'expliquer les réponses sinon nous produisons des script kiddies.
Josh Habdas
Et si vos branches sont toutes à la racine de SVN et que vous n'avez pas de tronc ou de balises?
Kal
58

Je suggère de se familiariser avec Git avant d'essayer d'utiliser git-svn en permanence, c'est-à-dire de conserver SVN comme référentiel centralisé et d'utiliser Git localement.

Cependant, pour une migration simple avec toute l'histoire, voici les quelques étapes simples:

Initialisez le référentiel local:

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

Marquez jusqu'où vous souhaitez commencer à importer des révisions:

git svn fetch -r42

(ou juste "git svn fetch" pour tous les tours)

Récupérez tout depuis:

git svn rebase

Vous pouvez vérifier le résultat de l'importation avec Gitk. Je ne sais pas si cela fonctionne sur Windows, cela fonctionne sur OSX et Linux:

gitk

Lorsque votre référentiel SVN est cloné localement, vous pouvez le pousser vers un référentiel Git centralisé pour faciliter la collaboration.

Créez d'abord votre référentiel à distance vide (peut-être sur GitHub ?):

git remote add origin [email protected]:user/project-name.git

Ensuite, vous pouvez éventuellement synchroniser votre branche principale pour que l'opération d'extraction fusionne automatiquement le maître distant avec votre maître local, lorsque les deux contiennent de nouveaux éléments:

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

Après cela, vous pourriez être intéressé à essayer mon propre git_remote_branchoutil, qui aide à gérer les branches distantes:

Premier message explicatif: " Git remote branches "

Suivi de la version la plus récente: "Il est temps de collaborer avec git_remote_branch "

webmat
la source
Extrêmement utile, cela a parfaitement fonctionné. J'ajouterais qu'il y a une dernière étape à franchir si vous synchronisez avec un référentiel distant. Après les étapes de configuration de git, je devaisgit push origin master
mag382
31

Il existe une nouvelle solution pour une migration en douceur de Subversion vers Git (ou pour utiliser les deux simultanément): SubGit .

Je travaille moi-même sur ce projet. Nous utilisons SubGit dans nos référentiels - certains de mes coéquipiers utilisent Git et Subversion et jusqu'à présent, cela fonctionne très bien.

Pour migrer de Subversion vers Git avec SubGit, vous devez exécuter:

$ subgit install svn_repos
...
TRANSLATION SUCCESSFUL 

Après cela, vous obtiendrez le référentiel Git dans svn_repos / .git et pourrez le cloner, ou tout simplement continuer à utiliser Subversion et ce nouveau référentiel Git ensemble: SubGit s'assurera que les deux sont toujours synchronisés.

Si votre référentiel Subversion contient plusieurs projets, plusieurs référentiels Git seront créés dans le répertoire svn_repos / git. Pour personnaliser la traduction avant de l'exécuter, procédez comme suit:

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

Avec SubGit, vous pouvez migrer vers Git pur (pas git-svn) et commencer à l'utiliser tout en conservant Subversion aussi longtemps que vous en avez besoin (pour vos outils de construction déjà configurés, par exemple).

J'espère que cela t'aides!

Alexander Kitaev
la source
4
Notez qu'une importation unique (à l'aide de la subgit importcommande) ne semble même pas nécessiter de licence. Une traduction précise de la svn:ignorepropriété dans des .gitignorefichiers est également incluse.
krlmlr
1
SubGit ne reconnaîtrait pas ma clé privée, ni aucun indicateur que j'ai défini dans la ligne de commande. La documentation est très pauvre. Ce n'est pas une alternative viable pour git svn.
pfnuesel
1
erreur: 'svn_repos' n'est pas un emplacement configuré valide; Le fichier de configuration SubGit est manquant.
Jon Davis
19

Voir la page de manuel git-svn officielle . En particulier, regardez sous "Exemples de base":

Suivi et contribution à l'ensemble d'un projet géré par Subversion (avec un tronc, des balises et des branches):

# Clone a repo (like git clone):
    git svn clone http://svn.foo.org/project -T trunk -b branches -t tags
EfForEffort
la source
Votre commande clone a fonctionné, celles ci-dessus ne m'ont donné que des git repos vides. La seule différence semble être le «tronc -T» explicite.
user1984717
14

SubGit (vs Blue Screen of Death)

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

C'est tout.

+ Pour mettre à jour depuis SVN, un référentiel Git créé par la première commande.

subgit import  directory/path/Local.git.Repo

J'ai utilisé un moyen de migrer instantanément vers Git pour un énorme référentiel.
Bien sûr, vous avez besoin d'une préparation.
Mais vous ne pouvez pas du tout arrêter le processus de développement.

Voici ma voie.

Ma solution ressemble à:

  • Migrer SVN vers un référentiel Git
  • Mettez à jour le référentiel Git juste avant le passage de l'équipe à .

La migration prend beaucoup de temps pour un grand référentiel SVN.
Mais mise à jour de la migration terminée en quelques secondes.

Bien sûr, j'utilise SubGit , maman. git-svn me fait Blue Screen of Death . Juste constamment. Et git-svn m'ennuie avec l' erreur fatale " Nom de fichier trop long " de Git .

PAS

1. Téléchargez SubGit

2. Préparez les commandes de migration et de mise à jour.

Disons que nous le faisons pour Windows (c'est trivial de porter sur Linux).
Dans l'installation d'un SubGit répertoire bin d' (subgit-2.XX \ bin), créez deux fichiers .bat.

Contenu d'un fichier / commande pour la migration:

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

La commande "start" est ici facultative (Windows). Cela permettra de voir les erreurs au démarrage et de laisser un shell ouvert après la fin du SubGit.

Vous pouvez ajouter ici des paramètres supplémentaires similaires à git-svn . J'utilise uniquement --default-domain myCompanyDomain.com pour corriger le domaine de l'adresse e-mail des auteurs SVN.
J'ai la structure du référentiel SVN standard (tronc / branches / balises) et nous n'avons eu aucun problème avec la "cartographie des auteurs". Alors je ne fais plus rien.

(Si vous souhaitez migrer des balises comme des branches ou votre SVN a plusieurs dossiers de branches / balises, vous pouvez envisager d'utiliser l' approche SubGit plus verbeuse )

Astuce 1 : Utilisez --minimal-revision YourSvnRevNumber pour voir rapidement comment les choses se résument (une sorte de débogage). Il est particulièrement utile de voir les noms d'auteur ou les e-mails résolus.
Ou pour limiter la profondeur de l'historique de migration.

Astuce 2 : la migration peut être interrompue ( Ctrl+C ) et restaurée par l'exécution de la prochaine commande / fichier de mise à jour.
Je ne conseille pas de faire cela pour les grands référentiels. J'ai reçu "Exception de mémoire Java + Windows insuffisante".

Astuce 3 : Mieux vaut créer une copie de votre référentiel nu.

Contenu d'un fichier / commande de mise à jour:

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

Vous pouvez l'exécuter autant de fois que vous le souhaitez pour obtenir les validations de la dernière équipe dans votre référentiel Git.

Attention! Ne touchez pas votre dépôt nu (création de branches par exemple).
Vous prendrez la prochaine erreur fatale:

Erreur irrécupérable: ne sont pas synchronisés et ne peuvent pas être synchronisés ... Traduction des révisions Subversion en Git commits ...

3. Exécutez la première commande / fichier. Cela prendra beaucoup de temps pour un grand référentiel. 30 heures pour mon humble dépôt.

C'est tout.
Vous pouvez mettre à jour votre référentiel Git à partir de SVN à tout moment et à tout moment en exécutant le deuxième fichier / commande. Et avant de passer de votre équipe de développement à Git.
Cela ne prendra que quelques secondes.



Il y a encore une tâche utile.

Poussez votre référentiel Git local vers un référentiel Git distant

Est-ce votre cas? Continuons.

  1. Configurez vos télécommandes

Courir:

$ git remote add origin url://your/repo.git
  1. Préparez-vous à l'envoi initial de votre énorme référentiel Git local vers un référentiel distant

Par défaut, votre Git ne peut pas envoyer de gros morceaux. fatal: l'extrémité distante a raccroché de façon inattendue

Courons pour lui:

git config --global http.postBuffer 1073741824

524288000 - 500 Mo 1073741824 - 1 Go, etc.

Corrigez vos problèmes de certificat local . Si votre git-server utilise un certificat cassé.

J'ai désactivé les certificats .

Votre serveur Git peut également avoir des limitations de quantité de demande devant être corrigées .

  1. Poussez toute la migration vers le référentiel Git distant de l'équipe.

Exécutez avec un Git local:

git push origin --mirror

( git push origin '*: *' pour les anciennes versions de Git)

Si vous obtenez ce qui suit: erreur: ne peut pas générer git: aucun fichier ou répertoire ... Pour moi, la recréation complète de mon référentiel résout cette erreur (30 heures). Vous pouvez essayer les commandes suivantes

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

Ou essayez de réinstaller Git ( inutile pour moi ). Ou vous pouvez créer des branches à partir de tous vos tags et les pousser. Ou, ou, ou ...

it3xl
la source
10

reposurgeon

Pour les cas compliqués, le reposurgeon d' Eric S. Raymond est l'outil de choix. En plus de SVN, il prend en charge de nombreux autres systèmes de contrôle de version via le fast-exportformat, ainsi que CVS . L'auteur rapporte des conversions réussies d'anciens référentiels tels qu'Emacs et FreeBSD .

L'outil vise apparemment une conversion presque parfaite (telle que la conversion des svn:ignorepropriétés de SVN en .gitignorefichiers) même pour les dispositions de référentiel difficiles avec une longue histoire. Dans de nombreux cas, d'autres outils peuvent être plus faciles à utiliser.

Avant de vous plonger dans la documentation de la reposurgeonligne de commande, assurez-vous de lire l'excellent guide de migration DVCS qui passe en revue le processus de conversion étape par étape.

Peter Mortensen
la source
8

Vous devez installer

git
git-svn

Copié à partir de ce lien http://john.albin.net/git/convert-subversion-to-git .

1. Récupérez une liste de tous les committers de Subversion

Subversion répertorie simplement le nom d'utilisateur pour chaque commit. Les validations de Git contiennent des données beaucoup plus riches, mais au plus simple, l'auteur de la validation doit avoir un nom et un e-mail répertoriés. Par défaut, l'outil git-svn listera simplement le nom d'utilisateur SVN dans les champs auteur et email. Mais avec un peu de travail, vous pouvez créer une liste de tous les utilisateurs SVN et de leur nom et de leurs e-mails Git correspondants. Cette liste peut être utilisée par git-svn pour transformer les noms d'utilisateur svn simples en committers Git appropriés.

À partir de la racine de votre extraction Subversion locale, exécutez cette commande:

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

Cela récupérera tous les messages du journal, arrachera les noms d'utilisateur, éliminera tous les noms d'utilisateur en double, triera les noms d'utilisateur et les placera dans un fichier «author-transform.txt». Modifiez maintenant chaque ligne du fichier. Par exemple, convertissez:

jwilkins = jwilkins <jwilkins>

en cela:

jwilkins = John Albin Wilkins <[email protected]>

2. Clonez le référentiel Subversion à l'aide de git-svn

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

Cela fera la transformation git-svn standard (en utilisant le fichier auteurs-transform.txt que vous avez créé à l'étape 1) et placera le référentiel git dans le dossier «~ / temp» à l'intérieur de votre répertoire personnel.

3. Convertir svn: ignorer les propriétés en .gitignore

Si votre dépôt svn utilisait les propriétés svn: ignore, vous pouvez facilement le convertir en un fichier .gitignore en utilisant:

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

4. Poussez le référentiel vers un référentiel nu git

Tout d'abord, créez un référentiel nu et faites en sorte que sa branche par défaut corresponde au nom de la branche «tronc» de svn.

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

Poussez ensuite le référentiel temporaire vers le nouveau référentiel nu.

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

Vous pouvez maintenant supprimer en toute sécurité le référentiel ~ / temp.

5. Renommez la branche «tronc» en «maître»

Votre branche de développement principale sera nommée «tronc», ce qui correspond au nom qu'elle était dans Subversion. Vous voudrez le renommer en branche «maître» standard de Git en utilisant:

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

6. Nettoyez les branches et les étiquettes

git-svn transforme toutes les balises Subversions en branches très courtes dans Git de la forme «balises / nom». Vous voudrez convertir toutes ces branches en tags Git réels en utilisant:

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

Cette étape prendra un peu de frappe. :-) Mais ne vous inquiétez pas; votre shell Unix fournira une invite secondaire pour la commande extra-longue qui commence par git for-each-ref.

Valarpirai
la source
7

GitHub dispose désormais d'une fonctionnalité à importer à partir d'un référentiel SVN . Mais je ne l'ai jamais essayé.

webmat
la source
3
La recommandation actuelle de GitHub est d'utiliser le svn2gitprogramme suggéré dans une autre réponse .
ntc2
Importé deux projets assez gros en ce moment sans faute. Toutes les branches SVN ont été importées (rappelez-vous juste de NE PAS utiliser la partie \ trunk dans le chemin du repo). Une chose que je ne sais pas encore, c'est si Github suivrait les nouveaux commits.
Fr0sT
7

Une réponse quelque peu étendue en utilisant juste git, SVN et bash. Il comprend des étapes pour les référentiels SVN qui n'utilisent pas la disposition conventionnelle avec une disposition de répertoire trunk / branches / tags (SVN ne fait absolument rien pour imposer ce type de disposition).

Utilisez d'abord ce script bash pour analyser votre dépôt SVN pour les différentes personnes qui ont contribué et pour générer un modèle pour un fichier de mappage:

#!/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

Utilisez-le pour créer un authorsfichier dans lequel vous mappez les noms d'utilisateur svn aux noms d'utilisateur et e-mail définis par vos développeurs à l'aide des git configpropriétés user.nameetuser.email (notez que pour un service comme GitHub, seul un e-mail correspondant suffit).

Ensuite, git svnclonez le référentiel svn dans un référentiel git, en lui parlant du mappage:

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

Cela peut prendre énormément de temps, car git svn vérifiera individuellement chaque révision pour chaque balise ou branche qui existe. (notez que les balises dans SVN ne sont que des branches, donc elles finissent comme telles dans Git). Vous pouvez accélérer cela en supprimant les anciennes balises et branches dans SVN dont vous n'avez pas besoin.

L'exécuter sur un serveur du même réseau ou sur le même serveur peut également vraiment accélérer cela. De plus, si pour une raison quelconque ce processus est interrompu, vous pouvez le reprendre en utilisant

git svn rebase --continue

Dans de nombreux cas, vous avez terminé ici. Mais si votre dépôt SVN a une disposition non conventionnelle où vous avez simplement un répertoire dans SVN que vous souhaitez mettre dans une branche git, vous pouvez faire quelques étapes supplémentaires.

Le plus simple est de simplement créer un nouveau dépôt SVN sur votre serveur qui respecte la convention et d'utiliser svn copypour mettre votre répertoire en tronc ou en branche. Cela pourrait être le seul moyen si votre répertoire est à la racine du référentiel, lors de ma dernière tentativegit svn simplement refusé de faire une vérification.

Vous pouvez également le faire en utilisant git. Pourgit svn clone simplement utiliser le répertoire que vous souhaitez mettre dans une branche git.

Après la course

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

Notez que cela nécessite Git 1.7 ou supérieur.

thoutbeckers
la source
Je proposerais de combiner cette information avec ce lien: sailmaker.co.uk/blog/2013/05/05/…
Joan PS
7

J'ai publié un guide étape par étape ( ici ) pour convertir svn en git, y compris la conversion des balises svn en balises git et des branches svn en branches git.

Version courte:

1) cloner svn à partir d'un numéro de révision spécifique. (le numéro de révision doit être le plus ancien que vous souhaitez migrer)

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

2) récupérer les données svn. Cette étape est celle qui prend le plus de temps.

cd gitreponame
git svn fetch

répéter git svn fetch jusqu'à ce qu'il se termine sans erreur

3) Obtenez la branche principale mise à jour

git svn rebase

4) Créez des branches locales à partir des branches svn en copiant les références

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

5) Convertissez les tags svn en tags 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) Mettez un référentiel à un meilleur endroit comme github

git remotes add newrepo [email protected]:aUser/aProjectName.git
git push newrepo refs/heads/*
git push --tags newrepo

Si vous voulez plus de détails, lisez mon post ou demandez-moi.

Pablo Belaustegui
la source
6

Nous pouvons utiliser les git svn clonecommandes comme ci-dessous.

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

La commande ci-dessus créera un fichier d'auteurs à partir des validations SVN.

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

La commande ci-dessus vous donnera le premier numéro de révision lorsque votre projet SVN a été créé.

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

La commande ci-dessus créera le référentiel Git en local.

Le problème est qu'il ne convertira pas les branches et les balises en push. Vous devrez les faire manuellement. Par exemple ci-dessous pour les succursales:

$ 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
$

Pour les tags:

$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
$

Maintenant, poussez master, branches et tags vers le dépôt git distant.

$ 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
$

utilitaire svn2git

L' utilitaire svn2git supprime les efforts manuels avec les branches et les balises.

Installez-le à l'aide de la commande sudo gem install svn2git. Après cela, exécutez la commande ci-dessous.

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

Vous pouvez maintenant lister les branches, les tags et les pousser facilement.

$ 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

Imaginez que vous ayez 20 branches et tags, évidemment svn2git vous fera gagner beaucoup de temps et c'est pourquoi je l'aime mieux que les commandes natives. C'est une belle enveloppe autour de la git svn clonecommande native .

Pour un exemple complet, reportez-vous à mon entrée de blog .

Pankaj
la source
3

Je recommande fortement cette courte série de screencasts que je viens de découvrir. L'auteur vous guide à travers les opérations de base et présente quelques utilisations plus avancées.

ripper234
la source
3

Si vous utilisez SourceTree, vous pouvez le faire directement depuis l'application. Goto File -> New / Clone puis procédez comme suit:

  1. Saisissez l'URL SVN distante comme "Chemin d'accès / URL source".
  2. Entrez vos informations d'identification lorsque vous y êtes invité.
  3. Entrez l'emplacement du dossier local comme "Chemin de destination".
  4. Donne lui un nom.
  5. Dans les options avancées, sélectionnez "Git" dans la liste déroulante "Créer un référentiel local de type".
  6. Vous pouvez éventuellement spécifier une révision à partir de laquelle cloner.
  7. Hit Clone.

Ouvrez le dépôt dans SourceTree et vous verrez que vos messages de validation ont également été migrés.

Maintenant, allez dans Référentiel -> Paramètres du référentiel et ajoutez les nouveaux détails du référentiel distant. Supprimez la télécommande SVN si vous le souhaitez (je l'ai fait via l'option "Modifier le fichier de configuration".

Poussez le code vers le nouveau référentiel distant lorsque vous êtes prêt et codez librement.

Craig Myles
la source
Merci, supereasy et rapide!
Rikard
Merci, cela a fonctionné pour moi, j'utilise SourceTree et Stash.
VK_217
3

Pour les utilisateurs de GitLab , j'ai mis en place un aperçu de la façon dont j'ai migré de SVN ici:

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

Étapes pour migrer de SVN vers GitLab

Installer

  • SVN est hébergé chez svn.domain.com.au.
  • SVN est accessible via http(d'autres protocoles devraient fonctionner).
  • GitLab est hébergé chez git.domain.com.auet:
    • Un groupe est créé avec l'espace de noms dev-team.
    • Au moins un compte d'utilisateur est créé, ajouté au groupe et possède une clé SSH pour le compte utilisé pour la migration (test à l'aide ssh [email protected]).
    • Le projet favourite-projectest créé dans l' dev-teamespace de noms.
  • Le fichier users.txtcontient les détails d'utilisateur pertinents, un utilisateur par ligne, du formulaire username = First Last <[email protected]>, où usernameest le nom d'utilisateur donné dans les journaux SVN. (Voir le premier lien dans la section Références pour plus de détails, notamment la réponse de l'utilisateur Casey).

Versions

  • version subversion 1.6.17 (r1128011)
  • git version 1.9.1
  • GitLab version 7.2.1 ff1633f
  • Serveur Ubuntu 14.04

Commandes

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 [email protected]:dev-team/favourite-project.git
git push --set-upstream gitlab master

C'est ça! Rechargez la page du projet dans l'interface utilisateur Web de GitLab et vous verrez tous les validations et fichiers maintenant répertoriés.

Remarques

  • S'il y a des utilisateurs inconnus, la git svn clonecommande arrête, dans ce cas, la mise à jour users.txt, cd favourite-projectet git svn fetchcontinuera d'où il est arrêté.
  • La norme trunk- tags- branchesmise en page pour le dépôt SVN est nécessaire.
  • L'URL SVN donnée à la git svn clonecommande s'arrête au niveau immédiatement supérieur trunk/, tags/et branches/.
  • La git svn clonecommande produit beaucoup de sortie, y compris certains avertissements en haut; J'ai ignoré les avertissements.
Xharze
la source
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien de référence. Les réponses de lien uniquement peuvent devenir invalides si la page liée change.
Blackhole
1
Je ne suis pas d'accord. Le contenu lié peut changer et le contenu dupliqué ici ne sera pas mis à jour et peut donc être obsolète (et en fait, je pense qu'il a changé depuis que j'ai initialement publié cette réponse). Les lignes directrices disent seulement d'inclure un contexte pertinent pour un lien, ce que j'ai fait - la vraie question a été répondue en gros par le lien. La copie de l'intégralité de la ressource liée ici n'est ni requise ni nécessaire. Ai-je été rétrogradé pour cela?!
leftclickben
2

En tant qu'autre côté, la commande git-stash est une aubaine lorsque vous essayez de git avec git-svn dcommits.

Un processus typique:

  1. configurer git repo
  2. travailler sur différents fichiers
  3. décidez de vérifier une partie du travail, en utilisant git
  4. décider de svn-dcommit
  5. obtenir l'erreur redoutée "ne peut pas valider avec un index sale".

La solution (nécessite git 1.5.3+):

git stash; git svn dcommit ; git stash apply
Gregg Lind
la source
2

Voici un script shell simple sans dépendances qui convertira un ou plusieurs référentiels SVN en git et les poussera vers GitHub.

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

Dans environ 30 lignes de script, il: clone à l'aide de git SVN, crée un fichier .gitignore à partir des propriétés SVN :: ignore, pousse dans un référentiel git nu, renomme le tronc SVN en maître, convertit les balises SVN en balises git et le pousse vers GitHub tout en préservant les balises.

J'ai eu beaucoup de mal à déplacer une douzaine de référentiels SVN de Google Code vers GitHub. Cela n'a pas aidé que j'utilise Windows. Ruby était cassé de toutes sortes sur mon ancienne boîte Debian et le faire fonctionner sous Windows était une blague. D'autres solutions n'ont pas pu fonctionner avec les chemins Cygwin. Même une fois que quelque chose a fonctionné, je n'arrivais pas à comprendre comment faire apparaître les balises sur GitHub (le secret est --follow-tags).

À la fin, j'ai bricolé deux scripts courts et simples, liés ci-dessus, et cela fonctionne très bien. La solution n'a pas besoin d'être plus compliquée que ça!

NateS
la source
2
J'ai utilisé ce script. Après un peu de traînée et d'erreur, cela a fonctionné pour moi. Veuillez noter que vous avez besoin de Git 1.8.3+ pour cela, car --follow-tags n'est pris en charge que par la suite.
nrobey
2

Je suis sur une machine Windows et j'ai fait un petit lot pour transférer un dépôt SVN avec l'historique (mais sans branches) vers un dépôt GIT en appelant simplement

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

Peut-être que n'importe qui peut l'utiliser. Il crée un dossier TMP extrait le dépôt SVN avec git et ajoute la nouvelle origine et la pousse ... et supprime à nouveau le dossier.

@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%

Vous avez toujours besoin du fichier users.txt avec vos mappages utilisateur comme

User1 = User One <[email protected]>
cljk
la source
Cette réponse m'a aidé à déplacer tous mes référentiels vers BitBucket sans problème.
Gonzalingui
Ravi d'entendre. Je n'avais qu'une expérience avec Gitea ... mais transféré ~~ 40 repos de cette façon.
cljk
Très agréable! Thnx
b3wii
Attention; J'ai rencontré de mauvais problèmes de jeu de caractères. J'ai reconnu cela vraiment trop tard mais cela m'a pris plusieurs heures à réparer. Veuillez vérifier que votre dépôt résultant contient les sources exactes (!)
Attendues
1

Je voulais juste ajouter ma contribution à la communauté Git. J'ai écrit un simple script bash qui automatise l'importation complète. Contrairement à d'autres outils de migration, cet outil s'appuie sur git natif au lieu de jGit. Cet outil prend également en charge les référentiels avec un historique de révision important et / ou des objets blob volumineux. Il est disponible via github:

https://github.com/onepremise/SGMS

Ce script convertira les projets stockés dans SVN au format suivant:

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

Ce schéma est également populaire et pris en charge également:

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

Chaque projet sera synchronisé par nom de projet:

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

Si vous souhaitez convertir le repo complet, utilisez la syntaxe suivante:

Ex: ./migration https://svnurl.com/basepath .
Jason Huntley
la source
0

Utiliser efficacement Git avec Subversion est une introduction en douceur à git-svn. Pour les dépôts SVN existants, git-svn rend cela super simple. Si vous démarrez un nouveau référentiel, il est beaucoup plus facile de créer d'abord un référentiel SVN vide, puis d'importer à l'aide de git-svn que dans la direction opposée. Créer un nouveau référentiel Git puis importer dans SVN peut être fait, mais c'est un peu pénible, surtout si vous êtes nouveau sur Git et espérez conserver l'historique des validations.

burkestar
la source
0

Téléchargez le programme d'installation de Ruby pour Windows et installez la dernière version avec. Ajoutez des exécutables Ruby à votre chemin.

  • Installer svn2git
  • Menu Démarrer -> Tous les programmes -> Ruby -> Démarrer une invite de commande avec Ruby
  • Tapez ensuite «gem install svn2git» et entrez

    Migrer le référentiel Subversion

  • Ouvrez une invite de commande Ruby et accédez au répertoire dans lequel les fichiers doivent être migrés

    Puis svn2git http: // [ nom de domaine ] / svn / [racine du référentiel]

  • La migration du projet vers Git peut prendre quelques heures en fonction de la taille du code du projet.

  • Cette étape majeure aide à créer la structure du référentiel Git comme mentionné ci-dessous.

    Tronc SVN (/ Project_components) -> Branches Git master SVN (/ Project_components) -> Branches Git Balises SVN (/ Project_components) -> Balises Git

Créez le référentiel distant et envoyez les modifications.

Nanda
la source
0

GitHub a un importateur. Une fois que vous avez créé le référentiel, vous pouvez importer à partir d'un référentiel existant, via son URL. Il vous demandera vos informations d'identification le cas échéant et partira de là.

Pendant son exécution, il trouvera des auteurs, et vous pouvez simplement les mapper aux utilisateurs sur GitHub.

Je l'ai utilisé pour quelques dépôts maintenant, et c'est assez précis et beaucoup plus rapide aussi! Il a fallu 10 minutes pour un dépôt avec ~ 4000 commits, et après cela a pris quatre jours à mon ami!

Josh Benson
la source
0

Plusieurs réponses se réfèrent ici à https://github.com/nirvdrum/svn2git , mais pour les grands référentiels, cela peut être lent. J'ai essayé d'utiliser https://github.com/svn-all-fast-export/svn2git à la place, qui est un outil avec exactement le même nom mais qui a été utilisé pour migrer KDE de SVN vers Git.

Un peu plus de travail pour le configurer, mais une fois terminé, la conversion elle-même a pris des minutes où l'autre script a passé des heures.

Zitrax
la source
0

Il existe différentes méthodes pour atteindre cet objectif. J'ai essayé certains d'entre eux et j'ai trouvé que ça fonctionnait vraiment avec juste git et svn installés sur Windows OS.

Conditions préalables:

  1. git sur windows (j'ai utilisé celui-ci) https://git-scm.com/
  2. svn avec les outils de la console installés (j'ai utilisé le tortue svn)
  3. Fichier de vidage de votre référentiel SVN. svnadmin dump /path/to/repository > repo_name.svn_dump

Étapes pour atteindre l'objectif final (déplacer tous les référentiels avec l'historique vers un git, d'abord un git local, puis à distance)

  1. Créez un référentiel vide (en utilisant les outils de la console ou tortoiseSVN) dans le répertoire REPO_NAME_FOLDER cd REPO_NAME_PARENT_FOLDER, mettez dumpfile.dump dans REPO_NAME_PARENT_FOLDER

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump Attendez cette opération, ça peut être long

  3. Cette commande est silencieuse, alors ouvrez la deuxième fenêtre cmd: svnserve -d -R --root REPO_NAME_FOLDER Pourquoi ne pas simplement utiliser file: /// ......? Parce que la prochaine commande échouera avec Unable to open ... to URL:, grâce à la réponse https://stackoverflow.com/a/6300968/4953065

  4. Créer un nouveau dossier SOURCE_GIT_FOLDER

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn: // localhost / Attendez cette opération.

Enfin, qu'avons-nous?

Permet de vérifier notre référentiel local:

git log

Voir vos commits précédents? Si oui - d'accord

Alors maintenant, vous avez un dépôt git local entièrement fonctionnel avec vos sources et votre ancien historique svn. Maintenant, si vous souhaitez le déplacer vers un serveur, utilisez les commandes suivantes:

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

Dans mon cas, je n'ai pas besoin de la commande tags car mon repo n'a pas de tags.

Bonne chance!

Ruslan Makrenko
la source
0

Conversion du sous-module / dossier svn 'MyModule' en git avec historique sans balises ni branches.

Pour conserver svn ignorer la liste, utilisez les commentaires ci-dessus après l'étape 1

PShetty
la source