tortoise - Solución para el error de "git svn clone"(que requiere el historial completo)
migrate svn to git with branches (5)
Me encontré con este problema cuando tenía subdirectorios con nombres idénticos dentro de sucursales o etiquetas.
Por ejemplo, tuve las etiquetas candidates/1.0.0
y releases/1.0.0
, y esto causó el error documentado porque el subdirectorio 1.0.0
aparece tanto en los candidates
como en los releases
.
Por documentos git-svn :
Cuando se utilizan múltiples --branches o --tags, git svn no maneja automáticamente las colisiones de nombres (por ejemplo, si dos ramas de diferentes rutas tienen el mismo nombre, o si una rama y una etiqueta tienen el mismo nombre). En estos casos, use init para configurar su repositorio Git y luego, antes de su primera búsqueda, edite el archivo $ GIT_DIR / config para que las ramas y etiquetas estén asociadas con diferentes espacios de nombre.
Entonces, mientras que el siguiente comando falló debido a candidates
nombres similares y releases
etiquetas:
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 siguiente secuencia de comandos funcionó:
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
Tenga en cuenta que esto solo funcionó porque no había otros conflictos dentro de las branches
y tags
. Si los hubiera, habría tenido que resolverlos de manera similar.
Después de clonar con éxito el repositorio SVN, ejecuté los siguientes pasos para: convertir las etiquetas SVN en etiquetas GIT; convertir trunk
en master
convertir otras referencias en ramas; y reubicar rutas remotas:
# 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
Quiero convertir un subdirectorio del repositorio Subversion (indicado aquí por el module
) en un repositorio git con historial completo. Hay muchas operaciones de svn copy
(la gente de Subversion las llama sucursales) en la historia de mi repositorio de Subversion. La política de liberación ha sido que después de cada lanzamiento u otras ramas creadas, la URL antigua se deja sin usar y la nueva URL reemplaza a la antigua por contener el trabajo.
De manera óptima, según mi lectura, parece que esto debería hacer el truco:
$ git svn clone --username=mysvnusername --authors-file=authors.txt /
--follow-parent /
http://svnserver/svn/src/branches/x/y/apps/module module
(donde branches/x/y/
representa la rama más nueva). Pero tengo un error, que se parece a esto:
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.
( Actualización: la opción de agregar --no-minimize-url
a lo anterior no elimina el mensaje de error).
El module
directorio se crea y se rellena, pero el historial de Subversion más allá de la nueva confirmación svn copy
no se importa (el repositorio git creado termina teniendo solo dos confirmaciones cuando esperaba cientos).
La pregunta es, ¿cómo exportar el historial completo de Subversion en presencia de esta situación?
Causa posible
Buscando el mensaje de error, encontré esto: la verificación anónima de git-svn falla con -s que se vinculó a este problema de Subversion: http://subversion.tigris.org/issues/show_bug.cgi?id=3242
Lo que entiendo por mi lectura, algo en Subversion 1.5 cambió acerca de cómo el cliente accede al repositorio. Con la versión más reciente de Subversion, si no hay acceso de lectura a algún super directorio de la ruta URL (es cierto para mí,
svn ls http://svnserver/svn
falla con403 Forbidden
), entonces fallamos con algunas operaciones de Subversion.Jeff Fairley en su respuesta señala que los espacios en la URL de Subversion también pueden causar este mensaje de error (confirmado por el usuario Owen). Eche un vistazo a su solución para ver cómo resolvió el caso si su
git svn clone
está fallando por la misma decisión.Dejay Clayton, en su respuesta, revela que si los componentes de subdirectorio más profundos en las URL svn de rama y etiqueta tienen el mismo nombre (por ejemplo
.../tags/release/1.0.0
y.../branches/release-candidates/1.0.0
), entonces este error podría ocurrir
No es una respuesta completa, pero quizás el fragmento que te falta (también me interesa migrar, así que encontré esa parte del rompecabezas).
Cuando mire la documentación de git-svn , encontrará la siguiente opción:
--no-minimize-url
Al rastrear múltiples directorios (usando las opciones --stdlayout, --branches o --tags), git svn intentará conectarse a la raíz (o nivel más alto permitido) del repositorio de Subversion. Este valor predeterminado permite un mejor seguimiento del historial si se mueven proyectos completos dentro de un repositorio, pero puede causar problemas en los repositorios donde existen restricciones de acceso de lectura. La transferencia de --no-minimizar-url permitirá a git svn aceptar las URL tal como están sin intentar conectarse a un directorio de nivel superior. Esta opción está desactivada de forma predeterminada cuando solo se rastrea una URL / rama (no serviría de mucho).
Esto se ajusta a la situación que tiene, por lo que git svn
no intenta leer un nivel superior del árbol de directorios (que se bloqueará).
Al menos podrías intentarlo ...
Recientemente, migré una larga lista de repositorios SVN a Git y hacia el final me topé con este problema. Nuestra estructura SVN era bastante descuidada, así que tuve que usar --no-minimize-url
un poco. Típicamente, ejecutaría un comando como:
$ git svn clone http://[url]/svn/[repo]/[path-to-code] /
-s --no-minimize-url /
-A authors.txt
Las últimas migraciones que corrí tenían un espacio en la URL. No sé si era el espacio o algo más, pero estaba recibiendo el mismo error que estaba viendo. No quería entrar en la modificación de los archivos de configuración si no tenía que hacerlo, y afortunadamente terminé encontrando una solución. Terminé saltándome las opciones -s --no-minimize-url
en favor de declarar explícitamente las rutas de manera diferente.
$ 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
- Tenga en cuenta que agregué
--follow-parent
en su ejemplo, pero tampoco estoy seguro de que haya alguna diferencia. - Recuerde que estos repositorios tenían espacios en ellos, por lo tanto,
""
alrededor de las rutas del tronco / ramas / etiquetas.
[ Me doy cuenta de que esto debería ser un comentario sobre la respuesta de Jeff Fairley, pero no tengo la reputación de publicarlo como tal. Como el póster original solicitó confirmación, el enfoque funcionó. Lo ofrezco como respuesta. ]
Puedo confirmar que su solución funciona para el problema que él (y yo) encontramos por los espacios en el camino. Tenía los mismos requisitos (clonar un solo módulo de un repositorio de SVN con historial), excepto que no tenía sucursales ni etiquetas de qué preocuparme.
Intenté varias permutaciones para proporcionar la ruta completa al módulo en la URL (p. Ej., Utilizando --no-minimise-url
, especificando --trunk
o --stdlayout
) sin éxito. Para mí, el resultado fue generalmente un repositorio de git con un registro de historial completo pero sin archivos. Este puede o no ser el mismo problema que FooF encontró (sin acceso de lectura en SVN), pero ciertamente fue causado por tener un espacio en la ruta a mi módulo.
Intentando de nuevo solo con la base de repo SVN como la URL y la ruta a mi módulo en --trunk
funcionó perfectamente. Después mi .git / config se ve así:
[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
y los comandos subsiguientes de git
y git svn
no generan ningún error. Gracias jeff
[Este es el póster original que habla escrito. Lo siguiente solía ser actualizado a la pregunta, pero como resolvió el caso, aunque no sea satisfactorio para mi gusto, lo publicaré como una respuesta que carece de una mejor solución.]
No me gusta esto, pero terminé haciendo clone
divididos en init
y fetch
con alguna edición 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
No pude encontrar la forma de especificar las ramas para la migración del subdirectorio con git svn
; de ahí la edición del archivo .git/config
. El siguiente diff unificado ilustra el efecto de la edición con 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/*
Como el HEAD
deseado real estaba en otra URL, terminé simplemente agregando otra sección [svn-remote]
a .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/*
(en el experimento de la vida real también agregué aquí algunas ramas que no fueron recogidas por la primera búsqueda), y recuperando nuevamente:
$ git svn fetch --authors-file=../authors.txt --follow-parent svn-newest
De esta manera terminé con el historial completo de Subversion migrado al repositorio de git recién generado.
Nota-1 : Probablemente podría haberle dicho a mi "troncal" que se branches/x/y/apps/module
ya que el significado de "troncal" para git-svn
parece tener básicamente el significado de git HEAD
(conceptos de subversión de troncal Las sucursales, las etiquetas no tienen una base técnica profunda, son materia de convención socialmente acordada.
Nota-2 : probablemente --follow-parent
no se requiere para git svn fetch
, pero ahora no tengo forma de saber o experimentar.
Nota-3 : Si bien la lectura anterior de svn2git que parece ser una envoltura sobre git-svn
, no pude ver la motivación, pero al ver la desordenada presentación de las etiquetas, ahora lo entiendo. svn2git
próxima vez si tuviera que intentar hacer esto otra vez.
PS Esta es una forma bastante incómoda de hacer la operación. El problema secundario aquí (por qué fue necesaria la edición de .git/config
por externo) parece ser que
- Las sucursales de Subversion no tienen un significado técnico esencial (las sucursales y las etiquetas en Subversion son simplemente etiquetas acordadas socialmente para una copia del sistema de archivos versionado junto con una convención estándar o de otra manera socialmente acordada donde se hacen las copias (el tronco no tiene un significado técnico) y
-
git svn
implementación degit svn
asume estrictamente las convenciones sociales de Subversion que deben seguirse en cierta medida (lo que no es posible si solo desea migrar un subdirectorio y no todo el repositorio de Subversion).
TODO: Sería útil tener el formato del archivo .git/config
explicado aquí en relación con git svn
; por ejemplo, ahora (después de un año y medio de escribir la respuesta original) no [svn-remote "svn-newest"]
idea de lo que [svn-remote "svn-newest"]
significa arriba. También se podría automatizar el enfoque al escribir un script, pero esto está más allá de mi interés actual en el problema y no tengo acceso al repositorio original de Subversion ni a la replicación del problema.