Bifurca y sincroniza el repositorio de Google Code Subversion en GitHub

131

¿Cómo puedo bifurcar y mantener la sincronización con un repositorio de Google Code Subversion al que no tengo acceso de escritura, en un repositorio de GitHub?

Quiero poder desarrollar mis propias características en mi repositorio de Git, pero también quiero sincronizar con el repositorio de Google Code Subversion. Para buscar arreglos desde el lado del proyecto de Google Code.

Sé acerca de git-svn y lo usé antes para subir y bajar a un repositorio de Subversion sobre el que tenía control total. Pero no sé cómo mantener la sincronización con un repositorio de Google Code Subversion.

optixx
fuente

Respuestas:

178

La rama remota de git-svn es prácticamente la misma que un control remoto Git normal. Entonces, en su repositorio local, puede tener su clon git-svn y enviar los cambios a GitHub. A Git no le importa. Si crea su clon git-svn y envía los mismos cambios a GitHub, tendrá un espejo no oficial del repositorio de Google Code. El resto es vainilla Git.

git svn clone http://example.googlecode.com/svn -s
git remote add origin [email protected]:example/example.git
git push origin master

Ahora que tiene esto, ocasionalmente tendrá que sincronizar el repositorio de Subversion con Git. Se verá algo así como:

git svn rebase
git push

En gitk o lo que sea, esto se vería así:

o [master][remotes/trunk][remotes/origin/master]
|
o
|
o

Y cuando corras git svn rebase, tendrías esto:

o [master][remotes/trunk]
|
o
|
o [remotes/origin/master]
|
o
|
o

Así que ahora ejecutar git pushenviaría esos commits a GitHub, el [control remoto / origen / maestro] rama allí. Y volvería al escenario en el primer diagrama de arte ASCII.

El problema ahora es, ¿cómo trabajas tus cambios en la mezcla? La idea es que nunca te comprometas en la misma rama en la que estás git-svn-rebase-ing y git-empujando. Necesita una rama separada para sus cambios. De lo contrario, terminaría cambiando sus cambios sobre los de Subversion, lo que podría molestar a cualquiera que clone su repositorio Git. ¿Sígueme? OK, entonces creas una rama, llamémosla "características". Y se compromete y lo envía a GitHub a la rama de características. Tu gitk se vería así:

o [features][remotes/origin/features]
|
o
|
o [master][remotes/trunk][remotes/origin/master]
|
o

Aquí tienes tu rama de características un par de confirmaciones antes de la rama de Google Code, ¿verdad? Entonces, ¿qué sucede cuando quieres incorporar cosas nuevas de Google Code? Corres git svn rebaseprimero y obtienes esto:

                           o [features][remotes/origin/features]
[master][remotes/trunk] o  |
                        |  o
                        o /
                        |/
                        o[remotes/origin/master]
                        |
                        o

Si git pushdomina, puede imaginar que [remotes / origin / master] está en el mismo punto que master. Pero su rama de características no tiene los cambios. Sus opciones ahora son fusionar master en funciones o volver a crear características. Una fusión se vería así

git checkout features
git merge master 

            o [features]
           /|
          / o [remotes/origin/features]
[master] o  |
         |  o
         o /
         |/
         o
         |
         o

Luego envías funciones a GitHub. He dejado los controles remotos para que master ahorre espacio, estarían en el mismo punto que [master] .

El enfoque de rebase es un poco más malvado: tendría que presionar con fuerza, ya que su empuje no sería una fusión de avance rápido (sacaría la rama de características de debajo de alguien que la clonó). Realmente no se considera correcto hacer esto, pero nadie puede detenerte si estás decidido. También facilita algunas cosas, como cuando los parches se aceptan en sentido ascendente en forma ligeramente modificada. Ahorraría tener que meterse con los conflictos, solo puede volver a redactar, omitir los parches actualizados. De todos modos, un rebase sería así:

git rebase master features

         o [features]
         |
         o
         |  o [remotes/origin/features]
[master] o  |
         |  o
         o /
         |/
         o
         |
         o

Y luego tendrías que hacer git push --forceeso. Puede ver por qué necesita forzarlo, la historia tiene un gran cisma desde los [controles remotos / origen / características] hasta el nuevo post-rebase actual [características] .

Todo esto funciona, pero es mucho esfuerzo. Si va a ser un contribuyente habitual, la mejor opción sería trabajar así durante un tiempo, enviar algunos parches en sentido ascendente y ver si puede obtener acceso de confirmación a Subversion. De lo contrario, tal vez no envíe sus cambios a GitHub. Manténgalos locales e intente que sean aceptados río arriba de todos modos.

richq
fuente
Gracias por las excelentes instrucciones. ( gitnovato aquí.) Pregunta rápida. Hice esto contra un gran repositorio SVN y salió a ~ 141 megabytes. Lo empujé a github y luego lo cloné de nuevo, y salió a 130 megabytes. Corrí git gcen ambos. ¿Qué podría explicar la diferencia?
mpontillo
... Lo averigué. Que necesitaba git push origin --mirror.
mpontillo
Funcionó de maravilla, ahora solo necesito decirle a los desarrolladores originales de googlecode que usen github conmigo: D
electblake
Esto no funcionó para mí con la -sopción para git svn clone, pero sin él el resto funcionó bien.
user1027169
15

servicio svn2github

El sitio web http://svn2github.com/ proporciona un servicio para bifurcar cualquier repositorio SVN de acceso público en Github (en https://github.com/svn2github/projectname ). Lo intenté; al presionar "Hacer un espejo" aparentemente no hizo nada durante unos segundos y mostró el mensaje "error", pero en realidad funcionó. De hecho, se creó el nuevo repositorio, que contiene el código del repositorio SVN.

Luego, bifurcaría el repositorio que crea y trabajaría en su propio tenedor. Luego enviaría sus cambios al proyecto ascendente utilizando su rastreador de errores.

Mirando los repositorios existentes bajo el usuario de Github del servicio (por ejemplo, "svn2github empujado para dominar en svn2github / haxe hace 5 horas"), parece que regularmente realiza cambios en el repositorio SVN. No hay información sobre quién ejecuta el servicio en el sitio web, por lo que no apostaría a que continúe ejecutándose indefinidamente, pero funciona por ahora (y si alguna vez se cae, aún puede actualizar manualmente su bifurcación).

Plataforma de lanzamiento

Si no está configurado para usar Git y Github, otra alternativa es usar Launchpad.net. Launchpad puede importar automáticamente repositorios SVN (también CVS) en una rama bzr personal. Para hacer esto, cree un proyecto de Launchpad, luego vaya a la nueva página de importación , seleccione Subversion e ingrese la URL (por ejemplo http://projectname.googlecode.com/svn/trunk/). Dependiendo del tamaño del proyecto, la importación inicial puede demorar algunas horas. Las importaciones posteriores se ejecutarán periódicamente.

Para obtener más documentación, consulte la Ayuda de VCS Imports on Launchpad .

Caracol mecánico
fuente
10

Un tutorial para la sincronización de Google Code a GitHub está disponible en fnokd.com . El autor utiliza un servidor remoto siempre activo y un trabajo cron para automatizar la sincronización y mantiene el tronco SVN en una rama de GitHub llamada "proveedor".

akaihola
fuente
1

Hmm .. En mi compañía estaba haciendo casi lo mismo. Simplemente tener ambos repositorios .svn y .git en el mismo directorio (comprueba svn repo y crea git repo en esta copia de trabajo).

Luego, usando svn up y git push hizo la cosa. Por supuesto, si diverges mucho, tendrás que fusionar las cosas a mano.

Marcin Gil
fuente
Claro, pero quiero evitar tener los metadatos .svn y esperaba que git pueda usar un repositorio svn como maestro de flujo descendente
optixx
Entonces, ¿no es posible usar git-svn para pagar repo y git push a github?
Marcin Gil el
0

No estoy muy seguro de qué es lo que desea, pero, por supuesto, puede extraerlo de un repositorio de subversión e impulsarlo a un repositorio de Git desde la misma copia de trabajo. Y también puede git svn dcommitvolver al repositorio de subversion. Sin embargo, no puede hacer que el repositorio de GitHub se sincronice con el repositorio de subversion. Además, cuando tiene confirmaciones en su copia de trabajo que aún no están en el repositorio de subversión, deberá volver a redactarlas si se actualizó el repositorio de subversión, forzándolo a git push --forcelas confirmaciones "nuevas" a GitHub.

Bombe
fuente
0

Encontré estas instrucciones en el blog de Yu-Jie Lin :

Primero clone el repositorio de Subversion y presione al Git:

git svn clone https://foo.googlecode.com/svn/ git-foo 
cd git-foo
git remote add git-foo [email protected]:username/foo.git 
git push git-foo master

Después de confirmar en el repositorio de Subversion, ejecute

cd /path/to/git-foo
git svn fetch 
git svn rebase 
git push git-foo master
Ellen Spertus
fuente