Enviar un repositorio Git existente a SVN

Resuelto cflewis asked hace 15 años • 18 respuestas

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

Mi asesor de doctorado pide a todos los estudiantes que mantengan su trabajo en un repositorio SVN alojado en la universidad. Encontré toneladas de documentación y tutoriales sobre cómo desplegar un repositorio SVN existente en Git, pero nada sobre cómo enviar un repositorio Git a un repositorio SVN nuevo. Supongo que debe haber alguna manera de hacer esto con una combinación de git-svn y una nueva rama y rebase y todos esos maravillosos términos, pero soy un novato en Git y no me siento seguro con ninguno de ellos.

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

Seré la única persona que se comprometa con SVN, si esto hace alguna diferencia.

cflewis avatar Mar 19 '09 11:03 cflewis
Aceptado

Yo también necesitaba esto, y con la ayuda de la respuesta de Bombe y un poco de manipulación, lo hice funcionar. Aquí está la receta:

Importar Git -> Subversión

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 punto 3, recibirás un mensaje críptico como este:

Usando un nivel superior de URL:protocol:///path/to/repo/PROJECT => protocol:///path/to/repo

Simplemente ignora eso.

Cuando ejecuta el n.° 5, es posible que obtenga conflictos. Resuélvalos agregando archivos con el estado "no fusionado" y reanudando la rebase. Con el tiempo, habrás terminado; luego sincronice nuevamente con el repositorio SVN, usando dcommit. Eso es todo.

Mantener los repositorios sincronizados

Ahora puede sincronizar desde SVN a Git usando los siguientes comandos:

git svn fetch
git rebase trunk

Y para sincronizar de Git a SVN, use:

git svn dcommit

nota final

Es posible que desees probar esto en una copia local, antes de aplicarlo a un repositorio en vivo. Puedes hacer una copia de tu repositorio Git en un lugar temporal; simplemente use cp -r, ya que todos los datos están en el repositorio mismo. Luego puede configurar un repositorio de pruebas basado en archivos, usando:

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

Y consulte 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 realizar cambios duraderos.

Anexo: Si te equivocasgit svn init

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

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

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

Luego puedes ejecutar git svn initde nuevo.

troelskn avatar Apr 21 '2009 14:04 troelskn

Así es como lo hicimos funcionar:

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

Abra .git/configy agregue lo siguiente (de Mantenimiento de 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, escribe esto:

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

Ahora, si se interrumpe aquí por cualquier motivo, escriba estas tres líneas:

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

Y finalmente, puedes comprometerte con SVN:

git svn dcommit

Nota: siempre elimino esa carpeta después.

Alex Rouillard avatar Jan 19 '2012 19:01 Alex Rouillard

El uso git rebasedirecto perderá la primera confirmación. Git lo trata de manera diferente y no puede cambiar su base.

Existe un procedimiento que preservará 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.

Inicializa git-svn:

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

El --prefix le proporciona ramas de seguimiento remoto como "svn/trunk", lo cual es bueno porque no obtiene nombres ambiguos si llama a su sucursal local simplemente "trunk". Y -ses un atajo para el diseño estándar de troncales/etiquetas/sucursales.

Obtenga el material inicial de SVN:

git svn fetch

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

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

Luego obtenga el hash de la confirmación del baúl vacío:

git rev-parse svn/trunk

Crea el injerto:

git replace --graft <root-commit-hash> <svn-trunk-commit-hash>

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

Haga que el injerto sea permanente:

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

Soltar el injerto:

git replace -d <root-commit-hash>

gitk aún debería aparecer svn/trunken la ascendencia de master.

Linealiza tu historial en la parte superior del tronco:

git svn rebase

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

git svn dcommit
 avatar May 05 '2009 13:05

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 confirmación única porque el directorio de su proyecto SVN todavía está vacío. Ahora vuelva a basar todo en ese compromiso git svn dcommity debería haber terminado. Sin embargo, arruinará seriamente tus fechas de compromiso.

Bombe avatar Mar 19 '2009 10:03 Bombe

Git -> SVN con historial de confirmaciones completo

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

Cómo:

  1. Tener un repositorio SVN donde queremos importar nuestro material y clonarlo 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 enviar 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 antiguo de git al repositorio actual:

    git fetch old-git master
    
  5. Extraiga la rama maestra del antiguo git remoto en una nueva rama llamada antigua en el repositorio actual:

    git checkout -b old old-git/master`
    
  6. Rebase para poner el HEAD encima de old-git/master. Esto mantendrá todas sus confirmaciones. Básicamente, lo que esto hace es tomar todo el trabajo realizado en Git y colocarlo encima del trabajo al que accede desde SVN.

    git rebase master
    
  7. Ahora regresa a tu rama maestra:

    git checkout master
    

    Y puede ver que tiene un historial de confirmaciones limpio. Esto es lo que desea enviar a SVN.

  8. Envía tu trabajo a SVN:

    git svn dcommit
    

Eso es todo. Es muy limpio, sin piratería y todo funciona perfectamente desde el primer momento. Disfrutar.

codingdave avatar Mar 03 '2016 12:03 codingdave