with subgit migrar branches svn git git-svn

svn - migrar - subgit



Empujando un repositorio Git existente a SVN (16)

¿Qué sucede si no desea comprometer todos los compromisos que realice en Git, en el repositorio SVN? ¿Qué pasa si solo desea enviar de forma selectiva los compromisos por la tubería? Bueno, tengo una mejor solución.

Guardo un repositorio local de Git donde todo lo que hago es buscar y fusionar desde SVN. De esa manera, puedo asegurarme de incluir todos los mismos cambios que SVN, pero mantengo mi historial de confirmación completamente separado de SVN.

Luego guardo una copia de trabajo local de SVN separada que está en una carpeta separada. Ese es el que hago para volver a SVN, y simplemente uso la utilidad de línea de comandos SVN para eso.

Cuando estoy listo para comprometer el estado de mi repositorio Git local a SVN, simplemente copio todo el lío de archivos en la copia de trabajo local de SVN y los confirmo desde allí utilizando SVN en lugar de Git.

De esta manera, nunca tendré que volver a basar, porque la reorganización es como la limpieza.

He estado haciendo todo mi trabajo en Git y empujando a GitHub. Estoy muy contento con el software y el sitio, y no deseo cambiar mis prácticas de trabajo en este momento.

Mi asesor de doctorado está pidiendo a todos los estudiantes que mantengan su trabajo en un repositorio SVN que se encuentra en la universidad. He encontrado toneladas de documentación y tutoriales a punto de desplegar un repositorio SVN existente en Git, pero nada acerca de empujar un repositorio Git a un repositorio SVN nuevo. Supongo que debe haber alguna forma de hacer esto con una combinación de git-svn y una nueva rama y rebasado y todos esos términos maravillosos, pero soy un novato de Git y no me siento seguro con ninguno de ellos.

Luego, solo quiero ejecutar un par de comandos para enviar confirmaciones a ese repositorio SVN cuando lo elija. Deseo seguir usando Git y simplemente hacer que el repositorio SVN refleje lo que hay en Git.

Seré la única persona comprometida con SVN, si esto marca alguna diferencia.


Así es como lo hicimos funcionar:

Clona tu repositorio Git en algún lugar de tu máquina.

Abra .git / config y agregue lo siguiente (desde Mantener un espejo SVN de solo lectura de un repositorio Git ):

[svn-remote "svn"] url = https://your.svn.repo fetch = :refs/remotes/git-svn

Ahora, desde una ventana de consola, escriba estos:

git svn fetch svn git checkout -b svn git-svn git merge master

Ahora, si se rompe aquí por cualquier razón, escriba estas tres líneas:

git checkout --theirs . git add . git commit -m "some message"

Y finalmente, puedes comprometerte a SVN:

git svn dcommit

Nota: siempre desecho esa carpeta después.


Cree un nuevo directorio en el repositorio de Subversion para su proyecto.

# svn mkdir --parents svn://ip/path/project/trunk

Cambie a su proyecto administrado por Git e inicialice git-svn.

# git svn init svn://ip/path/project -s # git svn fetch

Esto creará una única confirmación porque el directorio de su proyecto SVN todavía está vacío. Ahora vuelva a escribir todo en ese commit, git svn dcommit y debería estar listo. Sin embargo, seriamente arruinará tus fechas de compromiso.


En mi caso, tuve que iniciar un proyecto limpio desde SVN

$ Project> git svn init protocol://path/to/repo -s $ Project> git svn fetch

agrega todas tus fuentes de proyectos ...

$ Project> git add . $ Project> git commit -m "Importing project sources" $ Project> git svn dcommit


Hace poco tuve que migrar varios repositorios Git a SVN, y después de probar todas las soluciones que pude encontrar, lo que finalmente me funcionó fue Mercurial (sí, utilizando un tercer VCS). Usando esta guía , se me ocurrió el siguiente proceso (en Linux, pero la idea básica también debería funcionar en Windows).

  1. Los paquetes necesarios:

    $ sudo apt-get install git subversion mercurial python-subversion

  2. Mercurial debe configurarse agregando lo siguiente a ~/.hgrc :

    [extensions] hgext.convert=

  3. Cree algunos directorios de trabajo temporales (tuve varios repositorios para migrar, así que creé directorios para las versiones SVN y Git, para mantenerlos separados):

    $ mkdir svn $ mkdir git

  4. Hacer un repositorio SVN local vacío:

    $ svnadmin create svn/project

  5. Clona el repositorio de Git existente:

    $ git clone server/path/project.git git/project

  6. Que Mercurial haga lo suyo.

    $ hg convert --dest-type svn git/project svn/project

  7. Ahora el repositorio SVN debe contener el historial de confirmación completo, pero no con las marcas de tiempo originales. Si esto no es un problema, omita la siguiente parte del paso 11.

  8. Con un poco de trabajo, la fecha y la hora de cada compromiso se pueden cambiar . Como mis repositorios son bastante pequeños, me fue posible hacerlo manualmente. Primero, cree un gancho de pre-revprop-change en el repositorio de SVN con el siguiente contenido, para permitir la modificación de la propiedad necesaria:

    #!/bin/bash exit 0;

    Este script tiene que ser ejecutable:

    $ chmod +x svn/project/hooks/pre-revprop-change

  9. Mercurial creó una copia de trabajo del repositorio SVN, denominada project -wc, así que cámbielo y edite los tiempos de confirmación:

    $ cd project-wc $ svn propedit svn:date --revprop -r 1

    Ingrese la fecha y hora correctas (¡preste atención a las zonas horarias!) Y guarde. Debería recibir un mensaje que dice "Establecer un nuevo valor para la propiedad svn: fecha en la revisión 1".
    Ahora enjuague y repita para cualquier otra revisión.

  10. Opcionalmente, compruebe el historial de confirmaciones para asegurarse de que todo se vea bien:

    $ svn log -r 1:HEAD

    Luego vuelve a subir un nivel:

    $ cd ..

  11. Volcar el repositorio:

    $ svnadmin dump svn/project > project.dump

  12. Y carga el volcado en tu servidor de Subversion. ¡Hecho!

Este proceso probablemente también funcionaría directamente entre repositorios remotos, pero me resultó más fácil trabajar con los locales. Arreglar los tiempos de compromiso fue mucho trabajo, pero en general el proceso fue mucho más sencillo que cualquier otro método que encontré.


Me gustaría compartir una gran herramienta que se utiliza en la comunidad de WordPress llamada Scatter

Git complementos de WordPress y un poco de dispersión de la cordura

Esto permite a los usuarios poder enviar su repositorio Git a wordpress.org SVN automáticamente. En teoría, este código se puede aplicar a cualquier repositorio SVN.


Necesitaba enviar mi repositorio Git existente a un repositorio SVN vacío.

Así es como logré hacer esto:

$ 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

Funcionó sin problemas. Espero que esto ayude a alguien.

Como tuve que autorizarme con un nombre de usuario diferente al repositorio de SVN (mi origin usa autenticación de clave pública / privada), tuve que usar la propiedad --username .


Necesitaba esto también, y con la ayuda de la respuesta de Bombe + algunos jugueteando, lo conseguí funcionando. Aquí está la receta:

Importar Git -> Subversion

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

Después del # 3 obtendrás un mensaje críptico como este:

Usando un nivel más alto de URL: protocol:///path/to/repo/PROJECT => protocol:///path/to/repo

Solo ignora eso.

Cuando ejecuta el número 5, puede obtener conflictos. Resuélvalos agregando archivos con el estado "no fusionado" y reanudando el rebase. Eventualmente, habrás terminado; luego sincronice nuevamente con el repositorio SVN, usando dcommit . Eso es todo.

Manteniendo los repositorios sincronizados

Ahora puedes sincronizar desde SVN a Git, usando los siguientes comandos:

git svn fetch git rebase trunk

Y para sincronizar desde Git a SVN, usa:

git svn dcommit

Nota final

Es posible que desee probar esto en una copia local, antes de aplicar a un repositorio en vivo. Puedes hacer una copia de tu repositorio Git a un lugar temporal; simplemente use cp -r , ya que todos los datos están en el propio repositorio. A continuación, puede configurar un repositorio de pruebas basado en archivos, utilizando:

svnadmin create /home/name/tmp/test-repo

Y verifica una copia de trabajo usando:

svn co file:///home/name/tmp/test-repo svn-working-copy

Eso te permitirá jugar con las cosas antes de hacer cambios duraderos.

Anexo: Si te equivocas git svn init

Si ejecutó accidentalmente git svn init con la URL incorrecta y no era lo suficientemente inteligente como para realizar una copia de seguridad de su trabajo (no pregunte ...), no puede volver a ejecutar el mismo comando. Sin embargo, puede deshacer los cambios emitiendo:

rm -rf .git/svn edit .git/config

Y elimine la sección [svn-remote "svn"] .

A continuación, puede ejecutar git svn init nuevo.


Otra secuencia más que funcionó (con algunos comentarios en cada paso):

  1. Instalar git-svn y subversion toolkits:

    sudo apt-get install git-svn subversion

  2. Cambiar dentro del PROJECT_FOLDER

    cd PROJECT_FOLDER

  3. Cree la ruta del proyecto en el servidor de Subversion (desafortunadamente, el complemento git-svn actual tiene un defecto en comparación con TortoiseSVN). No puede almacenar el código fuente directamente en el PROJECT_FOLDER . En su lugar, de forma predeterminada, cargará todo el código en PROJECT_FOLDER/trunk .

    svn mkdir --parents protocol: /// path / to / repo / PROJECT_FOLDER / trunk -m "creando un marcador de posición de git repo"

Este es el lugar donde el trunk al final del camino es obligatorio

  1. Inicialice el contexto del complemento git-svn dentro de la carpeta .git

    git svn init -s protocol:///path/to/repo/PROJECT_FOLDER

    Este es el lugar donde el trunk al final del camino no es necesario.

  2. Obtener una información vacía del repositorio de Subversion

    git svn fetch

    Este paso ayuda a sincronizar el servidor Subversion con el complemento git-svn . Este es el momento en que el complemento git-svn establece remotes/origin ruta de remotes/origin y lo asocia con la subcarpeta trunk en el lado del servidor.

  3. Los antiguos cambios de Git se hicieron antes de que el complemento git-svn se involucrara en el proceso (este paso es opcional )

    git rebase origin/trunk

  4. Agregar archivos nuevos / modificados para confirmar (este paso es regular para las actividades de Git y es opcional )

    git add .

  5. Confirme los archivos recién agregados en el repositorio Git local (este paso es opcional y solo es aplicable si se ha usado el paso 7):

    git commit -m "Importing Git repository"

  6. Presionando todo el historial de cambios del proyecto en el servidor de Subversion:

    git svn dcommit


Propondría una instrucción muy corta en 4 comandos usando SubGit . Vea esta post para más detalles.


Puedes hacer un nuevo repositorio SVN. Exporte su proyecto de Git (enviando archivos .git). Agréguelo al repositorio de SVN (inicialice el repositorio con lo que tenía hasta ahora en Git). Luego use las instrucciones para importar repositorios SVN en un proyecto Git nuevo.

Pero esto perderá tu anterior historial de Git.


Si desea seguir trabajando con Git como su repositorio principal y solo necesita "exportar" las revisiones a SVN de vez en cuando, puede usar Tailor para mantener el repositorio de SVN sincronizado. Puede copiar revisiones entre diferentes sistemas de control de origen y actualizaría el SVN con los cambios que realice en Git.

No he intentado una conversión de Git a SVN, pero para un ejemplo de SVN -> SVN vea esta respuesta .



Solo quiero compartir algo de mi experiencia con la respuesta aceptada. Hice todos los pasos y todo estaba bien antes de ejecutar el último paso:

git svn dcommit

$ git svn dcommit

Uso del valor no inicializado $ u en la sustitución (s ///) en la línea /usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm.

Uso del valor no inicializado $ u en concatenación (.) O cadena en /usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm línea 101. refs / remotes / origin / HEAD: '' https://192.168.2.101/svn/PROJECT_NAME ''no se encuentra en'' ''

Encontré el hilo https://github.com/nirvdrum/svn2git/issues/50 y finalmente la solución que apliqué en el siguiente archivo en la línea 101 /usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm

Reemplacé

$u =~ s!^/Q$url/E(/|$)!! or die

con

if (!$u) { $u = $pathname; } else { $u =~ s!^/Q$url/E(/|$)!! or die "$refname: ''$url'' not found in ''$u''/n"; }

Esto solucionó mi problema.


Usar git rebase directamente perderá el primer commit. Git lo trata de manera diferente y no puede cambiarlo.

Existe un procedimiento que conservará el historial completo: http://kerneltrap.org/mailarchive/git/2008/10/26/3815034

Transcribiré la solución aquí, pero los créditos son para Björn.

Inicializar git-svn:

git svn init -s --prefix=svn/ https://svn/svn/SANDBOX/warren/test2

El prefijo le proporciona las ramas de seguimiento remoto como "svn / trunk", lo cual es bueno porque no obtiene nombres ambiguos si llama a su sucursal local solo "trunk". Y -s es un acceso directo para el diseño estándar de troncales / etiquetas / ramas.

Busca las cosas iniciales de SVN:

git svn fetch

Ahora busque el hash de su confirmación de raíz (debería mostrar una confirmación única):

git rev-list --parents master | grep ''^./{40/}$''

A continuación, obtener el hash del commit de tronco vacío:

git rev-parse svn/trunk

Crea el injerto:

echo <root-commit-hash> <svn-trunk-commit-hash> >> .git/info/grafts

Ahora, "gitk" debería mostrar svn/trunk como la primera confirmación en la que se basa su rama maestra.

Hacer el injerto permanente:

git filter-branch -- ^svn/trunk --all

Suelta el injerto:

rm .git/info/grafts

gitk aún debería mostrar svn/trunk en la ascendencia del maestro.

Linealiza tu historia sobre el tronco:

git svn rebase

Y ahora "git svn dcommit -n" debería decirle que se comprometerá con el tronco.

git svn dcommit


Git -> SVN con historial completo de confirmaciones

Tuve un proyecto Git y tuve que moverlo a SVN. Así lo hice, manteniendo todo el historial de cometidos. Lo único que se pierde es el tiempo de confirmación original, ya que libSVN establecerá la hora local cuando hagamos git svn dcommit .

Cómo:

  1. Tener un repositorio SVN donde queremos importar nuestras cosas y clonarlas con git-svn:

    git svn clone https://path.to/svn/repository repo.git-svn`

  2. Ve allí:

    cd repo.git-svn

  3. Agregue el control remoto del repositorio Git (en este ejemplo estoy usando C: /Projects/repo.git ). Quieres presionar a SVN y darle el nombre old-git:

    git remote add old-git file:///C/Projects/repo.git/

  4. Obtenga la información de la rama maestra del repositorio de git antiguo al repositorio actual:

    git fetch old-git master

  5. Verifique la rama maestra del control remoto old-git en una nueva rama llamada old en el repositorio actual:

    git checkout -b old old-git/master`

  6. Rebase para poner el HEAD encima de old-git / master. Esto mantendrá todos tus compromisos. Básicamente, lo que esto hace es tomar todo tu trabajo realizado en Git y ponerlo encima del trabajo al que estás accediendo desde SVN.

    git rebase master

  7. Ahora vuelve a tu rama maestra:

    git checkout master

    Y puedes ver que tienes un historial de compromiso limpio. Esto es lo que quieres empujar a SVN.

  8. Empuje su trabajo a SVN:

    git svn dcommit

Eso es todo. Está muy limpio, sin piratería, y todo funciona perfectamente fuera de la caja. Disfrutar.