web-dev-qa-db-fra.com

Transférer un référentiel Git existant vers un SVN

J'ai fait tout mon travail dans Git et poussé vers GitHub. Je suis très satisfait du logiciel et du site et je ne souhaite pas modifier mes pratiques de travail pour le moment.

Mon directeur de thèse demande à tous les étudiants de conserver leur travail dans un référentiel SVN hébergé à l'université. J'ai trouvé des tonnes de documentation et de tutoriels sur le point d'extraire un référentiel SVN existant dans Git, mais rien ne dit de placer un référentiel Git dans un nouveau référentiel SVN. Je m'attends à ce qu'il y ait un moyen de faire cela avec une combinaison de git-svn et d'une nouvelle branche et rebasant ainsi que de tous ces termes merveilleux, mais je suis un novice de Git et je ne me sens pas en confiance avec aucun d'eux.

Je souhaite ensuite simplement exécuter quelques commandes pour que les envois Push dans ce référentiel SVN soient choisis. Je souhaite continuer à utiliser Git et simplement que le référentiel SVN reflète ce qu'il y a dans Git.

Je serai la seule personne à avoir jamais adhéré à SVN, si cela fait une différence.

375
cflewis

J'avais besoin de ça aussi, et avec l'aide de la réponse de Bombe + quelques manipulations, je l'ai fait fonctionner. Voici la recette:

Import Git -> Subversion

1. cd /path/to/git/localrepo
2. svn mkdir --parents protocol:///path/to/repo/PROJECT/trunk -m "Importing git repo"
3. git svn init protocol:///path/to/repo/PROJECT -s
4. git svn fetch
5. git rebase Origin/trunk
5.1.  git status
5.2.  git add (conflicted-files)
5.3.  git rebase --continue
5.4.  (repeat 5.1.)
6. git svn dcommit

Après # 3, vous recevrez un message crypté comme celui-ci:

Utilisation d'un niveau d'URL plus élevé: protocol:///path/to/repo/PROJECT => protocol:///path/to/repo

Ignorez ça.

Quand vous exécutez # 5, vous pourriez avoir des conflits. Résolvez-les en ajoutant des fichiers avec l'état "unmerged" et en reprenant rebase. Finalement, vous aurez fini. puis synchronisez à nouveau vers le référentiel SVN, en utilisant dcommit. C'est tout.

Garder les dépôts synchronisés

Vous pouvez maintenant synchroniser de SVN vers Git en utilisant les commandes suivantes:

git svn fetch
git rebase trunk

Et pour synchroniser de Git vers SVN, utilisez:

git svn dcommit

Note finale

Vous voudrez peut-être essayer ceci sur une copie locale, avant de l'appliquer à un référentiel actif. Vous pouvez faire une copie de votre référentiel Git dans un emplacement temporaire. utilisez simplement cp -r, car toutes les données sont dans le référentiel lui-même. Vous pouvez ensuite configurer un référentiel de test basé sur des fichiers, en utilisant:

svnadmin create /home/name/tmp/test-repo

Et vérifiez une copie de travail en utilisant:

svn co file:///home/name/tmp/test-repo svn-working-copy

Cela vous permettra de jouer avec les choses avant de faire des changements durables.

Addendum: Si vous vous trompez git svn init

Si vous avez accidentellement exécuté git svn init avec la mauvaise URL et que vous n'étiez pas assez intelligent pour effectuer une sauvegarde de votre travail (ne pas demander ...), vous ne pouvez plus exécuter la même commande à nouveau. Vous pouvez cependant annuler les modifications en émettant:

rm -rf .git/svn
edit .git/config

Et supprimez la section [svn-remote "svn"] section.

Vous pouvez alors exécuter git svn init à nouveau.

395
troelskn

Voici comment nous l'avons fait fonctionner:

Clonez votre référentiel Git quelque part sur votre ordinateur.

Ouvrez le fichier .git/config et ajoutez les éléments suivants (à partir de Gestion d’un miroir SVN en lecture seule d’un référentiel Git):

[svn-remote "svn"]
    url = https://your.svn.repo
    fetch = :refs/remotes/git-svn

Maintenant, à partir d’une fenêtre de console, tapez ce qui suit:

git svn fetch svn
git checkout -b svn git-svn
git merge master

Maintenant, si ça casse pour une raison quelconque, tapez ces trois lignes:

git checkout --theirs .
git add .
git commit -m "some message"

Et enfin, vous pouvez vous engager sur SVN:

git svn dcommit

Remarque: je supprime toujours ce dossier par la suite.

29
Alex Rouillard

Utiliser git rebase directement perdra le premier commit. Git le traite différemment et ne peut pas le rebaser.

Il existe une procédure qui préservera l'historique complet: http://kerneltrap.org/mailarchive/git/2008/10/26/3815034

Je vais transcrire la solution ici, mais les crédits sont pour Björn.

Initialiser git-svn:

git svn init -s --prefix=svn/ https://svn/svn/SANDBOX/warren/test2

Le préfixe - vous donne des branches de suivi à distance telles que "svn/trunk", ce qui est bien parce que vous n’obtenez pas de noms ambigus si vous appelez votre branche locale simplement "trunk". Et -s est un raccourci pour la disposition standard tronc/balises/branches.

Récupérez le contenu initial de SVN:

git svn fetch

Recherchez maintenant le hachage de votre commit racine (devrait afficher un seul commit):

git rev-list --parents master | grep '^.\{40\}$'

Ensuite, récupérez le hash du commit de coffre vide:

git rev-parse svn/trunk

Créer la greffe:

echo <root-commit-hash> <svn-trunk-commit-hash> >> .git/info/grafts

Maintenant, "gitk" devrait afficher svn/trunk comme premier commit sur lequel votre branche master est basée.

Rendre le greffon permanent:

git filter-branch -- ^svn/trunk --all

Déposer la greffe:

rm .git/info/grafts

gitk devrait toujours afficher svn/trunk dans l'ascendance du maître.

Linéarisez votre histoire sur le tronc:

git svn rebase

Et maintenant, "git svn dcommit -n" devrait vous dire qu'il va s'engager dans trunk.

git svn dcommit
27
Dardo Sordi

Créez un nouveau répertoire dans le référentiel Subversion pour votre projet.

# svn mkdir --parents svn://ip/path/project/trunk

Passez à votre projet géré par Git et initialisez git-svn.

# git svn init svn://ip/path/project -s
# git svn fetch

Cela créera un seul commit car votre répertoire de projet SVN est toujours vide. Maintenant, rebasez tout sur ce commit, git svn dcommit et vous devriez avoir terminé. Cela va sérieusement gâcher vos dates de commit.

8
Bombe

Git -> SVN avec l'historique de validation complet

J'avais un projet Git et je devais le transférer sur SVN. Voici comment je l'ai fait, en gardant toute l'histoire du commit. La seule chose qui est perdue est l’heure de validation initiale puisque libSVN définira l’heure locale lorsque nous aurons git svn dcommit.

Comment:

  1. Avoir un dépôt SVN où nous voulons importer nos fichiers et le cloner avec git-svn:

    git svn clone https://path.to/svn/repository repo.git-svn`
    
  2. Va là-bas:

    cd repo.git-svn
    
  3. Ajoutez la télécommande du référentiel Git (dans cet exemple, j'utilise C: /Projects/repo.git). Vous voulez pousser vers SVN et lui donner le nom old-git:

    git remote add old-git file:///C/Projects/repo.git/
    
  4. Récupérez les informations de la branche master du référentiel old-git vers le référentiel actuel:

    git fetch old-git master
    
  5. Extrayez la branche principale de la télécommande old-git dans une nouvelle branche appelée old dans le référentiel actuel:

    git checkout -b old old-git/master`
    
  6. Rebase pour mettre le HEAD au-dessus de old-git/master. Cela maintiendra tous vos commits. En gros, cela prend tout votre travail effectué dans Git et le place au-dessus du travail auquel vous accédez depuis SVN.

    git rebase master
    
  7. Maintenant, retournez à votre branche principale:

    git checkout master
    

    Et vous pouvez voir que vous avez une histoire de commit propre. C'est ce que vous voulez pousser sur SVN.

  8. Poussez votre travail sur SVN:

    git svn dcommit
    

C'est tout. C'est très propre, pas de piratage informatique, et tout fonctionne parfaitement. Prendre plaisir.

7
codingdave

Je proposerais une instruction très courte en 4 commandes en utilisant SubGit . Voir ce post pour plus de détails.

4
Dmitry Pavlenko

J'avais besoin de valider mon référentiel Git existant dans un référentiel SVN vide.

Voici comment j'ai réussi à faire ceci:

$ git checkout master
$ git branch svn
$ git svn init -s --prefix=svn/ --username <user> https://path.to.repo.com/svn/project/
$ git checkout svn
$ git svn fetch
$ git reset --hard remotes/svn/trunk
$ git merge master
$ git svn dcommit

Cela a fonctionné sans problèmes. J'espère que ça aidera quelqu'un.

Comme je devais m'autoriser avec un nom d'utilisateur différent dans le référentiel SVN (ma Origin utilise l'authentification par clé privée/publique), je devais utiliser la propriété --username.

3
Jay Linski

Si vous souhaitez continuer à utiliser Git en tant que référentiel principal et que vous devez simplement "exporter" les révisions vers SVN de temps en temps, vous pouvez utiliser Tailor pour conserver le référentiel SVN synchronisé. Il peut copier des révisions entre différents systèmes de contrôle de source et mettre à jour le SVN avec les modifications apportées dans Git.

Je n'ai pas essayé de conversion Git-à-SVN, mais pour un exemple SVN -> SVN, voir cette réponse .

2
sth

Si vous n'avez pas besoin d'utiliser un SVN spécifique et que vous utilisez GitHub, vous pouvez utiliser leur connecteur SVN.

Plus d'informations ici: Collaboration sur GitHub avec Subversion

1
elMarioFredo

J'aimerais partager un excellent outil utilisé dans la communauté WordPress appelé Scatter

Les plugins WordPress Git et un peu de santé mentale 

Cela permet aux utilisateurs d’envoyer automatiquement leur référentiel Git à wordpress.org SVN. En théorie, ce code peut être appliqué à n’importe quel référentiel SVN.

1
r109

J'ai récemment dû migrer plusieurs référentiels Git vers SVN et, après avoir essayé toutes les solutions trouvées, ce qui a finalement fonctionné pour moi a été Mercurial (oui, avec un third VCS). En utilisant ce guide , j’ai développé le processus suivant (sous Linux, mais l’idée de base devrait également fonctionner sous Windows).

  1. Les forfaits nécessaires:

    $ Sudo apt-get install git Subversion Mercurial python-Subversion
    
  2. Mercurial doit être configuré en ajoutant les éléments suivants à ~/.hgrc:

    [extensions]
    hgext.convert=
    
  3. Créez des répertoires de travail temporaires (j'avais plusieurs référentiels à migrer, j'ai donc créé des répertoires pour les versions SVN et Git, afin de les garder séparés):

    $ mkdir svn
    $ mkdir git
    
  4. Créez un référentiel SVN local vide:

    $ svnadmin create svn/project
    
  5. Clonez le référentiel Git existant:

    $ git clone server/path/project.git git/project
    
  6. Laissez Mercurial faire son travail:

    $ hg convert --dest-type svn git/project svn/project
    
  7. À présent, le référentiel SVN doit contenir l'historique complet des validations, mais pas avec les horodatages d'origine. Si ce n’est pas un problème, passez à l’étape 11.

  8. Avec un peu de travail, la date et l'heure de chaque commit peuvent être changées . Comme mes dépôts sont assez petits, il était possible pour moi de le faire manuellement. Tout d'abord, créez un point d'ancrage pre-revprop-change dans le référentiel SVN avec le contenu suivant, afin de permettre la modification de la propriété nécessaire:

    #!/bin/bash
    exit 0;
    

    Ce script doit être rendu exécutable:

    $ chmod +x svn/project/hooks/pre-revprop-change
    
  9. Mercurial a créé une copie de travail du référentiel SVN, nommée project -wc, accédez-y et modifiez les temps de validation:

    $ cd project-wc
    $ svn propedit svn:date --revprop -r 1
    

    Entrez la date et l'heure correctes (faites attention aux fuseaux horaires!) Et enregistrez. Vous devriez recevoir un message disant "Définir une nouvelle valeur pour la propriété svn: date sur la révision 1".
    Maintenant, rincez et répétez chaque fois.

  10. Vous pouvez éventuellement vérifier l'historique de validation pour vous assurer que tout se passe bien:

    $ svn log -r 1:HEAD
    

    Puis remontez d'un niveau:

    $ cd ..
    
  11. Vider le référentiel:

    $ svnadmin dump svn/project > project.dump
    
  12. Et chargez le dump sur votre serveur Subversion. Terminé!

Ce processus fonctionnerait probablement aussi directement entre les dépôts distants, mais j’ai trouvé plus facile de travailler avec des dépôts locaux. La correction des temps de validation demandait beaucoup de travail, mais dans l’ensemble, le processus était beaucoup plus simple que n’importe quelle autre méthode que j’avais trouvée.

0
Indrek

Encore une autre séquence qui a fonctionné (avec quelques commentaires à chaque étape):

  1. Installer les kits d'outils git-svn et Subversion:

    Sudo apt-get install git-svn Subversion
    
  2. Basculer à l'intérieur du PROJECT_FOLDER

    cd PROJECT_FOLDER
    
  3. Créez le chemin du projet sur le serveur Subversion (malheureusement, le plugin git-svn actuel présente un défaut par rapport à TortoiseSVN). Il est impossible de stocker le code source directement dans le PROJECT_FOLDER. Au lieu de cela, par défaut, il téléchargera tout le code dans PROJECT_FOLDER/trunk.

    svn mkdir - protocole parentes: /// chemin/vers/dépôt/PROJECT_FOLDER/trunk -m "création d'un espace réservé pour le dépôt git"

C'est l'endroit où trunk à la fin du chemin est obligatoire

  1. Initialiser le contexte du plugin git-svn dans le dossier .git

    git svn init -s protocol:///path/to/repo/PROJECT_FOLDER
    

    C'est l'endroit où trunk à la fin du chemin est inutile

  2. Récupère une information de référentiel Subversion vide

    git svn fetch
    

    Cette étape aide à synchroniser le serveur Subversion avec le plugin git-svn. C’est le moment où le plugin git-svn établit le chemin remotes/Origin et l’associe au sous-dossier trunk du côté serveur.

  3. Les anciens commits Git Rebase sont survenus avant que le plugin git-svn soit impliqué dans le processus (cette étape est optionnel )

    git rebase Origin/trunk
    
  4. Ajouter des fichiers nouveaux/modifiés à valider (cette étape est normale pour les activités Git et est optionnel )

    git add .
    
  5. Commit les fichiers récemment ajoutés dans le référentiel Git local (cette étape est optionnel et n'est applicable que si l'étape 7 a été utilisée):

    git commit -m "Importing Git repository"
    
  6. Transférer l’historique des modifications du projet sur le serveur Subversion:

    git svn dcommit
    
0
Oleg Kokorin

Vous pouvez créer un nouveau référentiel SVN. Exportez votre projet Git (en développant les fichiers .git). Ajoutez-le au référentiel SVN (en l'initialisant avec ce que vous aviez jusqu'à présent dans Git) . Suivez ensuite les instructions pour importer des référentiels SVN dans un nouveau projet Git.

Mais cela perdra votre historique Git précédent. 

0
Vasil

il y a trois méthodes:

  1. rebase: comme les autres réponses

  2. commit id: trouver svn en premier id de commit et git en premier id de commit, écrivez leur dans .git/info/grafts: echo "git_id svn_id}" > .git/info/grafts puis git svn dcommit

  3. checkout chaque git commit, copie des fichiers dans svn_repo, svn commit

démonstration de bash: démonstration de github

v1.x: utiliser rebase et commit id

v2.x: utilise des fichiers de copie, puis svn commit

0
张耀文

Je veux juste partager une partie de mon expérience avec la réponse acceptée. J'ai fait toutes les étapes et tout allait bien avant d'exécuter la dernière étape:

git svn dcommit

$ git svn dcommit

Utilisation de la valeur non initialisée $ u en substitution (s ///) à /usr/lib/Perl5/vendor_Perl/5.22/Git/SVN.pm, ligne 101.

Utilisation de la valeur non initialisée $ u dans la concaténation (.) Ou dans la chaîne /usr/lib/Perl5/vendor_Perl/5.22/Git/SVN.pm, ligne 101 . réfs/télécommandes/origine/HEAD: ' https://192.168.2.101/svn/PROJECT_NAME ' introuvable dans ''

J'ai trouvé le fil https://github.com/nirvdrum/svn2git/issues/50 et enfin la solution que j'ai appliquée dans le fichier suivant à la ligne 101 / usr/lib/Perl5/vendor_Perl /5.22/Git/SVN.pm

J'ai remplacé

$u =~ s!^\Q$url\E(/|$)!! or die

avec

if (!$u) {
    $u = $pathname;
} 
else {
       $u =~ s!^\Q$url\E(/|$)!! or die
      "$refname: '$url' not found in '$u'\n";
}

Cela a résolu mon problème.

0
Pavel Slepiankou

Dans mon cas, j'ai dû initier un projet propre de SVN

$ Project> git svn init protocol://path/to/repo -s
$ Project> git svn fetch

ajoutez toutes vos sources de projet ...

$ Project> git add .
$ Project> git commit -m "Importing project sources"
$ Project> git svn dcommit
0
dangt85