Robots y modelos

Notas sobre pruebas, modelado y aventuras en Java y Android

Recuperando un repositorio SVN desde un clon de git-svn

with one comment

Hoy me vi en la necesidad de recuperar un repositorio SVN perdido a partir de un clon Git creado con git-svn. Miré y encontré cosas sobre cambiar la URL del repositorio, pero no me sirvieron de mucho: el problema es que sencillamente, el antiguo repositorio está kaput y punto.

Rebuscando y mezclando cosas de aquí y aquí, he conseguido una pequeña receta que puede que sirva a alguien. No recupera fechas y los autores sólo a medias, pero bueno, por lo menos recuperamos los datos de las revisiones en sí.

Supongamos que trabajo sólo sobre /tmp y que el clon creado con git-svn del repositorio SVN desparecido está en /tmp/original-git. Lo primero que tenemos que hacer es crear un nuevo repositorio SVN, con una única revisión con un fichero cualquiera, que tenga algún contenido (con un espacio sirve), para que git-svn lo pueda clonar y manejar bien. Para ello, ejecutaremos:

svnadmin create svn-recreado
svn co file:///tmp/svn-recreado recreado
cd recreado
echo " " > borra.me
svn add borra.me
svn ci -m "primera revisión"

Con esto ya tenemos la primera revisión con algún fichero no vacío. Esto es importante, ya que de lo contrario no podremos crear un clon con git-svn. Vamos a crear ese clon. Tal y como sugiere este enlace, necesitaremos la opción de configuración svn.addAuthorFrom si queremos conservar (aunque será en las descripciones y no en el nombre de usuario en sí) la autoría de cada revisión.,o hacer siempre “git svn dcommit –add-author-from”. Puestos a elegir, la primera opción evita despistes. Ejecutamos estas órdenes:

git config --global svn.addAuthorFrom true
git svn clone file:///tmp/svn-recreado recreado-git

Ya tenemos el repositorio SVN y su clon Git con la revisión inicial que necesitamos. Vamos a enviar las revisiones del antiguo repositorio SVN desde /tmp/original-git a /tmp/recreado-git:

cd /tmp/original-git
git push file:///tmp/recreado-git/.git master:refs/heads/old-svn

Con esto hemos empujado las revisiones de la rama principal del antiguo clon Git a una nueva rama llamada old-svn en recreado-git. Esta rama no guarda parentesco alguno con la rama master de recreado-git. Tendríamos algo así:

old-svn: A –> B –> C
master: D

Para que cuando hagamos “git svn dcommit” desde old-svn se envíen las revisiones A, B y C al repositorio SVN, se tienen que cumplir una serie de condiciones. La primera es retirar los git-svn-id de los mensajes de los commits (ya que hacen referencia a la antigua URL y números de revisión). Para eso tenemos git-filter-branch:

git filter-branch --msg-filter 'sed -e /^git-svn-id:/d' old-svn

Esto transforma todos los commits de la rama old-svn, cambiando el mensaje con un guión de sed (más información aquí). Lo que hace este filtro es, en las líneas que cumplen la expresión regular /^git-svn-id:/ (es decir, que empiezan por git-svn-id:) ejecutar la orden “d”, que efectivamente borra dicha línea.

Lo siguiente es crear el enlace D –> A entre las revisiones. Lo desconocía hasta hoy, pero Git permite hacerlo manualmente, utilizando el fichero .git/info/grafts, que consiste en una serie de líneas “<hijo> <padre1> <padre2>…” con los SHA1 correspondientes. Tendremos primero que averiguar los SHA-1 de la última revisión de la rama old-svn y master. Para eso, podemos utilizar git-rev-list:

echo `git rev-list old-svn | tail -1` `git rev-list master | tail -1` >> .git/info/grafts

Ahora, si ejecutamos:

git checkout old-svn
git log

Deberíamos de ver la primera revisión del nuevo repositorio SVN justo después de la primera de nuestro repositorio. Con esto hemos terminado las preparaciones. Cambiamos a la rama master, reunimos con old-svn y enviamos al repositorio SVN:

git checkout master
git merge old-svn
git svn dcommit

Una nota: es posible que se quede calado en mitad de una revisión, como un coche de segunda mano😀. Con arrancar el proceso de nuevo y continuar el dcommit sirve:

git checkout -f old-svn
git rebase master
git checkout master
git merge old-svn
git svn dcommit

Written by bluezio

13 de octubre de 2008 a 21:26

Publicado en Uncategorized

Tagged with , ,

Una respuesta

Subscribe to comments with RSS.

  1. […] Acá parece haber un tutorial cortito para utilizarlo (Google me devuelve muchísimos enlaces más por si es […]


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: