Mantener actualizado un mod de proyecto de código abierto mantenido por VCS mientras uso DVCS para administrar los cambios de mi mod

Me gustaría modificar un proyecto de código abierto en SVN.

Me gustaría usar Mercurial para mantener mi mod en el control de la versión. (La razón de Mercurial es que me gustaría hacer un seguimiento de los sets de cambios para poder dividir el mod en componentes; esto es necesario para trabajar con el proyecto OpenCart, por ejemplo, ya que no admite extensiones).

Cuando se actualice el proyecto de fuente abierta, me gustaría fusionar los cambios con mi mod.

Sería ideal si el proyecto original se llevó a cabo en DVCS, ya que podría simplemente dividir el proyecto y trabajar desde allí, pero, por desgracia, la familiaridad de SVN mantiene su uso fuerte y esto es fijo.

Entonces mi pregunta es, ¿cuál es el flujo de trabajo ideal para este escenario y cómo lo implemento?

No hay un flujo de trabajo "ideal" cuando cambias:

  • el VCS utilizado (Mercurial en lugar de SVN)
  • la estructura del repository ( varios subrepos con los repositorys nesteds vs. un repository central SVN)

Creo que el flujo de trabajo habitual en este caso implicaría parches :

  • Ayuda en la creación de parches
  • Archivo de parche

Esto se ilustra en parte en la página de Mercurial " Trabajar con repositorys de Subversion ".

Cuando quiere producir un parche para los mantenedores, es simple:

$ hg di -b -r last_svn_revision:your_tip > mybugfix.patch 

Es posible que desee search en Mercurial Queues , o simplemente utilizar su ednetworkingón de inspiración no vcs específico.

Usando mercurial con hg-subversion, puedes clonar el repository svn como un repository mercurial, y luego usar un MQ (o solo twigs) contra eso para almacenar tus cambios. Cuando se actualice el repository de svn en sentido ascendente, extraerá su clon hg-subversion creado sin modificar y luego se fusionará en su clon modificado.

Dado que su repository "ascendente" es Subversion, puede utilizar una combinación de las queues Mercurial , Rebase y Convertir extensiones para realizar un seguimiento de las modificaciones locales astackdas en la parte superior de la fuente ascendente.

La idea general es que puede elegir una twig de Subversion desde el repository "ascendente" y usar la extensión Convertir para generar un clon local de Mercurial con el historial de la twig específica, por ejemplo:

  ________ (________) | | Subversion repository (________) | | hg convert svn+ssh://host/repo/branch svn-branch | v .------------------. | | | svn-branch/.hg | | | `------------------' 

La extensión de conversión puede extraer sets de cambios de Subversion de forma incremental en el futuro también, por lo que puede configurar un trabajo de cron que actualice su copy local "limpia" del código de flujo ascendente.

A continuación, puede crear tantos clones locales como desee de svn-branch , por ejemplo:

  ________ (________) | | Subversion repository (________) | | hg convert svn+ssh://host/repo/branch svn-branch | | | .-------------. | .-----> | feature-1 | v | `-------------' .------------------. | | | clone | .-------------. | svn-branch/.hg | -----------+-----> | feature-2 | | | | `-------------' `------------------' | | .-------------. +-----> | bugfix-1 | `-------------' 

Una vez que configura sus clones locales, tiene dos opciones para sus propios parches:

  • Confirme sus propios cambios como sets de cambios mercuriales en feature-1 , feature-2 o bugfix-1 y siga 'fusionándose' con el clon upstream de svn-branch
  • Mantenga sus propios cambios en la característica-1, etc. como parches de MQ, y vuelva a establecer una base de ellos cada vez que aparezca un set de sets de cambios en sentido ascendente en el espejo svn-branch local.

Ambos enfoques tienen sus pros y sus contras.

Cambios locales con sets de cambios 'normales'

Si tu intención es solo mantener una function local y no te importa enviar un "parche limpio" a los desarrolladores originales, entonces las hg pull periódicas de hg pull y hg merge son ideales. Las fusiones repetidas serán fáciles. Los conflictos serán mínimos. Puede realizar un seguimiento de cuándo, quién, qué se fusionó y por qué. Más importante aún: puedes compartir y publicar cómodamente tu clon modificado localmente con otras personas. Y así.

Con un repository svn-branch/.hg que tiene un historial de subversión casi lineal, las fusiones repetidas se verán así (los sets de cambios entre paréntesis son confirmaciones "solo locales"):

 [0] --- [1] --- [2] --- [4] --- [5] --- [7] --- [8] --- [9] --- [10] \ \ \ `-- (3) ------- (6) -------------------------- (11) 

Los cambios locales en el set de cambios (3) no son visibles para las personas de Subversion ascendentes, pero se puede ver en la historia local que se fusionaron dos veces con el código ascendente: en confirmaciones (6) y (11). Dado que cada combinación se registra como un set de cambios normal en Mercurial, es fácil ver quién realizó la fusión, cuándo, qué se fusionó, etc. También es muy fácil verificar cuáles son los cambios locales en cualquier punto de fusión, por ejemplo ejecutando:

 hg diff -r 5:6 hg diff -r 10:11 

Incluso puede registrar los sets de cambios locales en una twig con nombre , por ejemplo, al confirmar los cambios de (3) con:

 hg branch feature-1 hg commit -m "Message" 

Luego, mirando los diffs del código del proveedor "ascendente" puede usar el nombre de la twig:

 hg diff -r default:feature-1 

Depende de usted cómo realizará un seguimiento de las fusiones locales y la cantidad de información local que desea mantener.

Cambios locales con Colas Mercurial

Si está desarrollando un parche local "en aislamiento", y planea enviar el parche como un "clean diff" para los desarrolladores de Subversion aguas arriba, entonces MercurialQueues combinado con la extensión Rebase hace que sea fácil mantener sus parches "en la parte superior" de el espejo svn local. Todo el process de rebase de sus parches locales a menudo es tan fácil como:

 # Incrementally pull changesets from the upstream Subversion # repository into a local hg clone: cd ~/work/svn-branch hg convert svn+ssh://host/repo/branch . # Rebase the local patches of 'feature-1' on top of the # latest subversion commits: cd ~/work/feature-1 hg qpush -a && hg pull --rebase 

Crear una "queue de parches" local en uno de los clones de su espejo svn-branch es el primer paso:

 cd ~/work/feature-1 hg qinit -c 

Luego puede hacer los cambios locales y savelos como un parche de MQ:

 emacs src/foo.c hg qnew --git --force --edit 

Puede crear tantos parches locales como desee además de los commits de svn-branch originales. Por ejemplo, mi espejo local favorito de FreeBSD ahora incluye los siguientes parches:

 keramida@kobe:/hg/bsd/src$ hg qseries -s newvers-hg-support: Include the hg changeset number to uname output too. kernconf-kobe: Add a kernel config file for my laptop, based on GENERIC truss-style: Style nits for lines that are too long after recent truss changes. yacc-core-dump: Fix a yacc(1) core dump reported by darrenr; patch by ru loader-prompt: Lowercase the "OK" prompt of the boot-loader top-rawcpu: Make top(1) use raw (non-weighted) cpu mode by default, like ps(1) nogames-mtree: Fix `make installworld' when WITHOUT_GAMES=yes. typo-fixes: Fix misc typos in source code comments & docs mg-00-import: Import a snapshot of the mg(1) editor from OpenBSD mg-01-freebsd-changes: Adapt the OpenBSD code of mg(1) to FreeBSD's environment mg-02-build: Attach the mg(1) editor to the FreeBSD build process regression-chmod: Add a few regression tests for chmod(1) regression-stdtime: Add a regression suite for libc/stdtime functions keramida@kobe:/hg/bsd/src$ 

Ciertamente es posible mantener una stack local de cientos de cambios. MQ es bastante conveniente para desarrollar los parches localmente, ajustarlos , dividirlos o unirlos en sets de parches más grandes, y cuando se combina con la extensión Rebase es una forma poderosa de mantener su parche local 'moviéndose' a lo largo de la historia ascendente.

Los cambios de historial equivalentes para el parche de changeset (3) del ejemplo anterior serían algo como esto:

 # History snapshot #1 - the local changes in (3) as an # MQ patch P1 on top of changeset [2] from svn-branch: [0] --- [1] --- [2] --- (P1) 

Luego, cuando realizas algunas confirmaciones de subversión más en el clon svn-branch , puedes volver a establecer la base del parche local P1 sobre el último código svn:

 # History snapshot #2 - patch P1 rebased from [2] to the # latest svn-base commit: [0] --- [1] --- [2] --- [3] --- [4] --- (P1') . . (P1) . . hg rebase . ^ 

Después de unos días más, puede convertir más cambios de subversión en svn-branch y volver a establecer la base una vez más:

 # History snapshot #3 - patch P1' rebased from [4] to the # latest svn-base commit, as a possibly very modified # version, shown as patch P1'': [0] --- [1] --- [2] --- [3] --- [4] --- [5] --- [6] --- [7] --- [8] --- (P1'') . . (P1) . . . . hg rebase. . . . . . . . ^ 

Puedes seguir modificando tu parche local tantas veces como sea posible. Incluso puede volver a establecer la base de múltiples parches en cada iteración. Puede insert parches en el 'medio' de una queue de múltiples parches. Puede eliminar parches. Puede unir diffs, dividirlos en más parches, reorganizar el order de astackmiento de los parches. En general, puede reescribir y ajustar la queue de parches tantas veces como quiera.