Recreando tags svn en git de forma retrospectiva

Convertí un repository de Subversion en Git hace un par de semanas, pensé que todo parecía estar bien, y luego pasé a trabajar exclusivamente con git. Sin embargo, ahora noto que cometí un error al convertir tags y twigs.

El repository SVN tenía una jerarquía de tags. Entonces, por ejemplo, teníamos algo así como:

branches project1 1.0 1.1 project2 1.0.0.1 

etc. Ahora tengo git 'tags' project1 y project2. Intenté crear las tags anidadas ejecutando git ls-tree project1 , luego git tag project1-1.0 <hash> , pero si trato de verificar la label resultante recibo el post "No se puede cambiar la twig a una no confirmación". Veo que he labeldo un tree en lugar de un compromiso.

¿Hay alguna manera inteligente de crear tags manualmente?

Si miras en gitk (activando la vista de todas las twigs) y encuentras la twig project1 , podrás ver todas las confirmaciones en esa twig. Revisa y encuentra el que debe labelrse, y luego usa la git tag <hash> . Repita para las otras tags 🙂

Gracias a @stuart por ponerme en el path correcto. El process que utilicé fue un poco largo, pero creo que tengo los resultados correctos.

Primero, creé un file que contenía enlaces svn a mis carpetas 'padre' de tags (las que contienen las tags numeradas en versión). Procesé ese file para crear otro que contenga las routes de acceso contenidas en cada uno de esos padres:

 #!/usr/bin/python import os f = open('parents') parentPaths = [x.strip('\n') for x in f.readlines()] f.close() for parentPath in parentPaths: escapedPath = parentPath.replace('\\','\\\\').replace('/', '\\/').replace('&', '\\&') c = "svn ls '" + parentPath + "' | sed -e 's/\\(.*\\)/" + escapedPath + "\\/\\1/' >> paths" os.system(c) 

Luego obtuve los numbers de revisión de SVN para cada una de esas routes usando esta secuencia de commands:

 #!/usr/bin/python import os f = open('paths') ps = [ x.strip('\n') for x in f.readlines() ] f.close() for p in ps: branchName = p.replace("svn://myrepo/tags/", "").strip(" ").rstrip("/\n").replace("/", "-").replace(" ", "-").replace(")", "").replace("(", "").lower() eBN = branchName.replace("\\", "\\\\").replace("/", "\\/").replace("&", "\\&") c = "svn log '" + p + "' --stop-on-copy -l 1 -v | grep -E '\\(from .*:[0-9]+\\)$' | sed -e 's/.*(from .*:\\([0-9]*\\))$/\\1/' >> revs/" + eBN os.system(c) 

Una label puede contener varias inputs de revisión de logging SVN, por lo que envié el resultado de lo anterior a un solo file llamado revs.out:

 #!/usr/bin/python import os o = open('revs.out', 'w') for filename in os.listdir('revs') : f = open('revs/' + filename) l = [ x.strip('\n') for x in f.readlines() ] f.close() o.write( "{0} {1}\n".format( max(l), filename ) ) o.close() 

Esto contiene, por ejemplo:

 4073 myproject-version-1.12.44 6982 myproject-version-1.13.9 

El siguiente poco se vuelve un poco complicado. La mayoría de las tags se crearon en el tronco, y obtuve los commits de git para esos (ejecutando en un repository git):

 #!/usr/bin/python import os f = open('../svn/revs.out') revs = [ x.strip('\n').split(' ') for x in f.readlines() ] f.close() for rev in revs: r = rev[0] n = rev[1] c = "git log --all --grep '[email protected]" + r + " ' --pretty=format:%H | sed -e 's/\\(.*\\)/git tag " + n + " \\1\\n/' >> ~/src/svn/genTags.sh" os.system(c) 

Se crearon otras tags a partir de twigs, o desde carpetas en la jerarquía de troncales, o bien se crearon tags vacías cuando se creó una nueva carpeta en la jerarquía 'tags'. Estos casos los manejé casi de forma manual.

El resultado en este punto fue un script que a su vez crearía tags git. Aquí hay un extracto:

 git tag project1-1.2.0.2 86e0f47f37ee28a3b16be26e4ab81a39a24015aa git tag project2-1.1.0.2 9cefabc1e8e66e974bb3d987a1089027535c8562 git tag project2-1.1.0.8 1d3e9abe6f4ec440806d32ed60ae80a2568778eb 

Luego ejecuté el script para crear las tags.