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.
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:
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.
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
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.
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.
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.
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
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.
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:
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`
Va là-bas:
cd repo.git-svn
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/
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
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`
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
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.
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.
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
.
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 .
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
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.
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).
Les forfaits nécessaires:
$ Sudo apt-get install git Subversion Mercurial python-Subversion
Mercurial doit être configuré en ajoutant les éléments suivants à ~/.hgrc
:
[extensions]
hgext.convert=
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
Créez un référentiel SVN local vide:
$ svnadmin create svn/project
Clonez le référentiel Git existant:
$ git clone server/path/project.git git/project
Laissez Mercurial faire son travail:
$ hg convert --dest-type svn git/project svn/project
À 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.
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
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.
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 ..
Vider le référentiel:
$ svnadmin dump svn/project > project.dump
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.
Encore une autre séquence qui a fonctionné (avec quelques commentaires à chaque étape):
Installer les kits d'outils git-svn
et Subversion
:
Sudo apt-get install git-svn Subversion
Basculer à l'intérieur du PROJECT_FOLDER
cd PROJECT_FOLDER
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
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
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.
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
Ajouter des fichiers nouveaux/modifiés à valider (cette étape est normale pour les activités Git et est optionnel )
git add .
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"
Transférer l’historique des modifications du projet sur le serveur Subversion:
git svn dcommit
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.
il y a trois méthodes:
rebase: comme les autres réponses
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
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
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.
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