Je souhaite convertir un sous-répertoire de référentiel de subversion (indiqué par module
ici) dans un référentiel GIT avec une histoire complète. Il existe de nombreux opérations svn copy
(les personnes subversion les appellent des succursales) dans l'historique de mon référentiel Subversion. La stratégie de version a été celle après chaque version ou d'autres branches créées, l'ancienne URL est laissée inutilisée et la nouvelle URL remplace l'ancien pour contenir le travail.
De manière optimale, par ma lecture, on dirait que cela devrait faire l'affaire:
$ git svn clone --username=mysvnusername --authors-file=authors.txt \
--follow-parent \
http://svnserver/svn/src/branches/x/y/apps/module module
(où branches/x/y/
décrit la nouvelle branche). Mais j'ai eu une erreur qui ressemble à quelque chose comme ça:
W: Ignoring error from SVN, path probably does not exist: (160013): Filesystem has no item: '/svn/src/!svn/bc/100/branches/x/y/apps/module' path not found
W: Do not be alarmed at the above message git-svn is just searching aggressively for old history.
( Mise à jour: Ajout d'une option --no-minimize-url
à ce qui précède ne supprime pas le message d'erreur.)
Le répertoire module
Obtenez créé et peuplé, mais l'historique de subversion au-delà du Dernier svn copy
commit n'est pas importé (le référentiel git créé finit par avoir seulement deux commits lorsque je m'attendais à des centaines).
La question est de savoir comment exporter l'historique complet de la subversion en présence de cette situation?
Recherche du message d'erreur, j'ai trouvé ceci: Checkout git-svn anonyme échoue avec -s qui est lié à ce problème de subversion: http://subversion.tigris.org/issues/show_bug .cgi? id = 3242
Ce que je comprends par ma lecture, quelque chose dans Subversion 1.5 a changé sur la manière dont le client accède au référentiel. Avec une nouvelle subversion, s'il n'y a pas d'accès en lecture à certains super répertoires du chemin de l'URL (true pour moi, svn ls http://svnserver/svn
échoue avec 403 Forbidden
), puis nous échouons avec certaines opérations de subversion.
Jeff Fairley dans sa réponse souligne que les espaces de l'URL de Subversion pourraient également causer ce message d'erreur (confirmé par l'utilisateur Owen). Regardez sa solution pour voir comment il a résolu le cas si votre git svn clone
échoue pour le même Resson.
Dejay Clayton dans sa réponse révèle que si les composants de sous-répertoire les plus profonds des URL de la branche et des étiquettes SVN sont également nommés (par exemple, .../tags/release/1.0.0
et .../branches/release-candidates/1.0.0
), cette erreur pourrait se produire.
J'ai rencontré ce problème lorsque j'avais des sous-répertoires nommés à l'intérieur des branches ou des balises.
Par exemple, j'ai eu des tags candidates/1.0.0
et releases/1.0.0
, et cela a provoqué l'erreur documentée parce que le sous-répertoire 1.0.0
apparaît dans les deux candidates
et releases
.
Par - GIT-SVN Docs :
Lorsque vous utilisez plusieurs branches ou --tags, Git SVN ne gère pas automatiquement les collisions de noms (par exemple, si deux branches de différents chemins ont le même nom, ou si une branche et une balise ont le même nom). Dans ces cas, utilisez INIT pour configurer votre référentiel git puis, avant votre première extraction, modifier le fichier $ git_dir/config pour que les branches et les balises soient associées à des espaces de noms différents.
Ainsi, alors que la commande suivante a échoué à cause de la même manière nommée candidates
et releases
balises:
git svn clone --authors-file=../authors.txt --no-metadata \
--trunk=/trunk --branches=/branches --tags=/candidates \
--tags=/releases --tags=/tags -r 100:HEAD \
--prefix=Origin/ \
svn://example.com:3692/my-repos/path/to/project/
la séquence de commandes suivante a fonctionné:
git svn init --no-metadata \
--trunk=/trunk --branches=/branches --tags=/tags \
--prefix=Origin/ \
'svn://example.com:3692/my-repos/path/to/project/'
git config --add svn-remote.svn.tags \
'path/to/project/candidates/*:refs/remotes/Origin/tags/Candidates/*'
git config --add svn-remote.svn.tags \
'path/to/project/releases/*:refs/remotes/Origin/tags/Releases/*'
git svn fetch --authors-file=../authors.txt -r100:HEAD
Notez que cela ne fonctionnait que parce qu'il n'y avait pas d'autres conflits dans branches
et tags
. S'il y en avait, j'aurais dû devoir les résoudre de la même manière.
Après avoir correctement cloné le référentiel SVN, j'ai ensuite exécuté les étapes suivantes afin de: Tournez les balises SVN en balises GIT; Tour trunk
dans master
; transformer les autres références dans des branches; et déplacer des chemins distants:
# Make tags into true tags
cp -Rf .git/refs/remotes/Origin/tags/* .git/refs/tags/
rm -Rf .git/refs/remotes/Origin/tags
# Make other references into branches
cp -Rf .git/refs/remotes/Origin/* .git/refs/heads/
rm -Rf .git/refs/remotes/Origin
cp -Rf .git/refs/remotes/* .git/refs/heads/ # May be missing; that's okay
rm -Rf .git/refs/remotes
# Change 'trunk' to 'master'
git checkout trunk
git branch -d master
git branch -m trunk master
Pas une réponse complète, mais peut-être l'extrait que vous manquez (je suis intéressé à migrer aussi bien, j'ai donc trouvé cette partie du puzzle).
Lorsque vous regardez la Documentation de git-svn , vous trouverez l'option suivante:
--no-minimize-url
Lors du suivi de plusieurs répertoires (à l'aide de --STDlayout, --Branches ou --Tags Options), Git SVN tentera de se connecter à la racine (ou au niveau autorisé le plus élevé) du référentiel de subversion. Cette valeur par défaut permet un meilleur suivi de l'historique si des projets entiers sont déplacés dans un référentiel, mais peuvent causer des problèmes sur des référentiels où des restrictions d'accès en lecture sont en place. Passage --No-Minimize-URL permettra à GIT SVN d'accepter des URLS, sans tenter de se connecter à un répertoire de niveau supérieur. Cette option est désactivée par défaut lorsque une seule URL/branche est suivie (cela ferait peu de bien).
Cela correspond à la situation que vous avez, de sorte que git svn
N'essaie pas de lire un niveau supérieur de l'arborescence de répertoire (qui sera bloqué).
Au moins vous pourriez essayer d'essayer ...
J'ai récemment migré une longue liste de référentiels SVN en Git et vers la fin courait dans ce problème. Notre structure SVN était jolie bâclée, alors j'ai dû utiliser --no-minimize-url
un peu. Typiquement, je dirais une commande comme:
$ git svn clone http://[url]/svn/[repo]/[path-to-code] \
-s --no-minimize-url \
-A authors.txt
Les dernières migrations que j'ai couru ont eu un espace dans l'URL. Je ne sais pas si c'était l'espace ou autre chose, mais j'avais la même erreur que vous voyiez. Je ne voulais pas entrer dans la modification des fichiers de configuration si je n'avais pas eu et j'ai fini par trouver une solution. J'ai fini par sauter le -s --no-minimize-url
options en faveur de déclarer explicitement les chemins différemment.
$ git svn clone http://[url]/svn/[repo]/ \
--trunk="/[path-to-code]/trunk" \
--branches="/[path-to-code]/branches" \
--tags="/[path-to-code]/tags" \
-A authors.txt \
--follow-parent
--follow-parent
De votre exemple, mais je ne suis pas sûr que cela a fait une différence.""
autour des chemins du tronc/des branches/des tags.[-Je me rends compte que cela devrait être un commentaire sur la réponse de Jeff Fairley, mais je n'ai pas la réputation de la publier comme tel. Puisque l'affiche originale a demandé une confirmation que l'approche a fonctionné que je lui fournis une réponse.]
Je peux confirmer que sa solution fonctionne pour le problème qu'il (et i) a couru causé par des espaces sur le chemin. J'ai eu les mêmes exigences (cloner un seul module d'un SVN Repo avec l'historique), sauf que je n'avais aucune branche ni étiquettes à craindre de ce que ce soit.
J'ai essayé plusieurs permutations de fournir le chemin complet du module de l'URL (par exemple en utilisant --no-minimise-url
, en précisant --trunk
ou --stdlayout
) sans succès. Pour moi, le résultat était généralement un repo git avec un journal d'historique complet mais aucun fichier que ce soit. Cela peut ou non être le même problème que FOOF rencontré (aucun accès en lecture dans SVN), mais il était certainement causé par une place dans le chemin de mon module.
Essayer à nouveau avec seulement la base de repo SVN comme URL et le chemin de mon module en --trunk
travaillé parfaitement. Ensuite, mon .git/config ressemble à ceci:
[core]
repositoryformatversion = 0
filemode = false
bare = false
loggallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
[svn-remote "svn"]
url = https://[url]/svn/[repo]
fetch = trunk/[path-to-code]:refs/remotes/trunk
[svn]
authorsfile = ~/working/authors-transform.txt
et ultérieur git
et git svn
Les commandes ne jettent aucune erreur. Merci jeff!
[Ceci est l'affiche originale parlant l'écriture. Le ci-dessous était mis à jour à la question, mais comme il résolvait le cas - bien que peu satisfaisants à mon goût - je le posterai comme une réponse sans une meilleure solution.]
Je n'aime pas ça, mais j'ai fini par faire clone
_ divisé dans init
et fetch
avec une modification de .git/config
entre (repopath=apps/module
, gitreponame=module
):
$ git svn init--username=mysvnusername \
--branches=/src/branches/ \
--trunk=/src/trunk/${repopath} \
--tags=/src/tags/ \
http://svnserver/svn/src ${gitreponame}
$ cd ${gitreponame}
$ sed -i.bak "s|*:|*/${repopath}:|" .git/config
$ git svn fetch --authors-file=../authors.txt --follow-parent
Je ne pouvais pas trouver comment spécifier les succursales pour la migration sous-répertoire avec git svn
- D'où l'édition du .git/config
déposer. Le diff de difformité unifié suivant illustre l'effet de la modification avec sed
:
[svn-remote "svn"]
url = http://svnserver/svn/src
fetch = trunk/apps/module:refs/remotes/trunk
- branches = branches/*:refs/remotes/*
- tags = tags/*:refs/remotes/tags/*
+ branches = branches/*/apps/module:refs/remotes/*
+ tags = tags/*/apps/module:refs/remotes/tags/*
Comme le réel souhaité HEAD
était dans une autre URL, j'ai fini simplement en ajoutant un autre [svn-remote]
section à .git/config
:
+ [svn-remote "svn-newest"]
+ url = http://svnserver/svn/src
+ fetch = branches/x/y/apps/module:refs/remotes/trunk
+ branches = branches/*/apps/module:refs/remotes/*
+ tags = tags/*/apps/module:refs/remotes/tags/*
(Dans une expérience réelle, j'ai également ajouté ici certaines branches qui n'ont pas été ramassées par la première extraction) et récupérant à nouveau:
$ git svn fetch --authors-file=../authors.txt --follow-parent svn-newest
De cette façon, j'ai fini par avoir l'historique de subversion complète émigré au référentiel Git nouvellement généré.
Note-1 : J'aurais probablement pu viens de dire à mon "tronc" d'être branches/x/y/apps/module
comme la signification de "coffre" pour git-svn
semble essentiellement avoir la signification de git HEAD
(Concepts de Subversion du tronc, des branches, des balises ne sont pas une base technique profonde, elles sont une question de convention socialement acceptée).
Note-2 : probablement --follow-parent
n'est pas requis pour git svn fetch
, mais je n'ai aucun moyen de savoir ni d'expérimenter maintenant.
Note-3 : tandis que la lecture antérieure de SVN2Git qui semble être une enveloppe sur git-svn
J'ai échoué à voir la motivation, mais voyant la présentation désordonnée des tags, je l'obtiens en quelque sorte. Je voudrais essayer svn2git
La prochaine fois si je devais essayer de le faire à nouveau.
P.s. C'est une façon plutôt délicat de faire l'opération. Problème secondaire ici (pourquoi l'édition du .git/config
par externe était requis) semble être que
git svn
La mise en œuvre suppose strictement les conventions de subversion sociale à suivre à un degré (ce qui n'est pas possible si vous souhaitez simplement migrer un sous-répertoire et non le référentiel de subversion entiers). TODO: Il serait utile d'avoir le format de la .git/config
Fichier expliqué ici car il se rapporte à git svn
- Par exemple, j'ai maintenant (après une et une demi année d'écriture de la réponse originale) aucune idée de ce que le [svn-remote "svn-newest"]
signifie ci-dessus. L'approche pourrait également être automatisée en écrivant un script, mais cela dépasse mon intérêt actuel dans le problème et je n'ai pas accès au référentiel de subversion d'origine ni à la réplication du problème.