Sincronización automática de un repository Subversion y un repository Git

Mi proyecto tiene un repository de Subversion en un sistema de files de networking, y un nuevo equipo desea acceder a él usando Git, y ser capaz de comprometerse con él y get actualizaciones de él.

Lo que tengo en mente es crear un nuevo clon git-svn desnudo del repository Subversion en el mismo sistema de files de networking, y asegurarme de que los dos repositorys estén siempre actualizados entre sí.

La forma de hacerlo es, probablemente, agregar un enlace post-commit tanto para Subversion como para el nuevo repository de Git, que cada uno actualizará el repository del otro.

El enlace post-commit de Subversion includeá git svn rebase y el Git one git svn dcommit .

El problema es que tendré que usar algún tipo de locking para asegurarme de que nadie se comprometa con ninguno de los repositorys mientras que otros también se comprometen, porque siempre deben estar sincronizados antes de cualquier confirmación. Esto tiene varias desventajas, entre ellas, el time que tomará comprometerse con Subversion o pasar al repository de Git (tiene que esperar a que el gancho termine), y el hecho de que algunos usuarios pueden no ser capaces de ejecutar git svn ( porque no está instalado en su máquina), lo que significa que no pueden actualizar el otro repository al confirmar / presionar.

¿Cómo puedo resolver estos problemas? ¿Cómo serán los ganchos de Subversion y Git?

Esto es lo que se me ocurrió:

  1. Crea el repository git-svn si no existe ya:

     git svn init --std-layout <svn_url> <git-svn_path> 

    La twig master se crea automáticamente para rastrear el trunk .

  2. Para evitar ambigüedades de nombres con las twigs de seguimiento de Subversion, haga que las twigs de Subversion originales se muestren como remotes/svn/<branch name> : vaya al repository de git-svn recién creado y ejecútelo

     git config svn-remote.svn.fetch trunk:refs/remotes/svn/trunk git config svn-remote.svn.branches branches/*:refs/remotes/svn/* git config svn-remote.svn.tags tags/*:refs/remotes/svn/tags/* rm .git/refs/remotes/* git svn fetch 
  3. Cree una twig de seguimiento de Subversion para cada sucursal de Subversion:

     for BRANCH in $(svn ls <svn_url>/branches/); do git branch $BRANCH remotes/svn/$BRANCH done 
  4. Asegúrese de que no se creen twigs que no sean de rastreo de Subversion en el repository central de Git:

     # Used by hooks/update: git config hooks.denyCreateBranch true git config hooks.allowDeleteBranch false cp .git/hooks/update.sample .git/hooks/update chmod +x .git/hooks/update 
  5. Permitir empujar al repository central de Git:

     git config receive.denyCurrentBranch ignore git config receive.denyNonFastForwards true git config push.default current 

    Y crea el enlace posterior a la recepción para restablecer y enviar los commits a Subversion:

     cat .git/hooks/post-receive #!/bin/sh date >> receive.log git reset --quiet --hard while read LINE do BRANCH=${LINE##*/} echo Updating $BRANCH git checkout --quiet --force $BRANCH git svn dcommit done 2>&1 | tee -a receive.log git checkout --quiet --force master chmod +x .git/hooks/post-receive 

    El reinicio es necesario, porque de lo contrario la twig actual está desactualizada después de cada recepción.

  6. Finalmente, crea el gancho para get actualizaciones de Subversion:

     cat .git/hooks/svn-rebase-all #!/bin/sh date >> .git/svn-rebase.log git reset --quiet --hard for REF in .git/refs/heads/* do BRANCH=${REF##*/} echo Updating $BRANCH git checkout --quiet --force $BRANCH git svn rebase done 2>&1 | tee -a .git/svn-rebase.log git checkout --quiet --force master chmod +x .git/hooks/svn-rebase-all 

    Y llámalo del enlace post-commit de Subversion:

     cat <svn_path>/hooks/post-commit cd <git_path> . .git/hooks/svn-rebase-all chmod +x <svn_path>/hooks/post-commit 

En lugar de usar un solo repository central de git-svn , uno puede usar un repository de Git central y un repository de git-svn intermedio no desnudo, como en esta respuesta . Elegí usar un repository git-svn no desnudo que también es el repository central.

Cualquiera puede trabajar en el proyecto usando Git clonando <git_path> y empujándolo, o usando Subversion revisando <svn_url> y comprometiéndose a ello.

Es mejor que solo cada desarrollador aprenda a usar git-svn directamente. Simplemente existe una falta de adecuación de impedancia entre los models de git y SVN para poder implementar de manera robusta lo que estás buscando. La única manera en que podría hacer que funcione incluso de manera casi confiable sería promulgar el mismo tipo de restricciones que tendría git-svn , pero con más partes mobilees que podrían romperse. En mi opinión, su sistema de control de revisiones no es el tipo de cosa que desea que sea parcialmente confiable.

Alternativamente, simplemente descarte SVN por completo y muévase hasta llegar a git, si es posible.