2010-06-29 10 views
12

Estoy trabajando en un proyecto que está usando código de un proyecto OpenSource. Uno de los requisitos es empujar la mayor cantidad de código posible hacia arriba.Trabajando en sincronización con SVN upstream

El proyecto remoto está utilizando Subversion (no muy bien).

Mi configuración actual es el siguiente:

[Remote SVN] (git svn fetch)-> [My public Git] <-(push/pull)-> [My dev. Git] 
            VV 
            (pull) 
            VV 
           [Testing grid] 

EDITAR 11.7. - reformulé la pregunta

Mi problema es la coexistencia de mi repos public local y el svn upstream.

tengo que proporcionar 3 ramas públicas:

  • conservadora estable
  • experimental estable de desarrollo

Estas ramas son ahora lineal (desarrollo se convierte experimental estable y experimental se vuelve conservadora) , pero el objetivo es un enfoque estándar de 3 cabezas con fusión. Debido a su naturaleza pública, no puedo volver a clasificar estas ramas.

Ahora, de forma totalmente ortogonal a esto, estoy intentando de alguna manera facilitar el envío de parches al flujo ascendente. Sacarlos de mis ramas es lento y propenso a errores.

Mi flujo de trabajo actual típico es:

  • implementar alguna característica en la rama de desarrollo superior
  • prueba & función Fijar
  • prueba & fijar otras características rotas por esta nueva función (que realmente sucede mucho)
  • determinar si esto es algo que podría aceptarse en la fase inicial o no (30:60 sí: no)
  • hacer algo al respecto (yo simplemente escribe una nueva TODO)

Otro problema con el upstream es que aceptan parches en diferentes ramas (mis ramas públicas se basan en su rama estable). Una vez que los parches alcanzan la rama estable, simplemente puedo olvidar que existen, pero hasta que eso ocurra, necesito mantenerlos localmente.

+1

su tarea es similar a esta http://hgbook.red-bean.com/read/advanced-uses-of-mercurial-queues.html. Resuelto con la pila de parches gestionada por "Mercurial Queues". No sé si hay tal utilidad para git – Alsk

+0

@Alsk Esto de hecho parece similar. Gracias por el consejo. –

Respuesta

28

El git svn documentation recomienda el siguiente flujo de trabajo cuando se trata de ramas de Subversion:

# Clone a repo (like git clone): 
git svn clone http://svn.example.com/project -T trunk -b branches -t tags 

# Append svn:ignore settings to the default git exclude file: 
git svn show-ignore >> .git/info/exclude 

# View all branches and tags you have cloned: 
git branch -r 

# Create a new branch in SVN 
git svn branch waldo 

# Reset your master to waldo: 
git reset --hard remotes/waldo 

# local changes 
git add ... 
git commit ... 

# pull changes on current branch 
git svn rebase 

# send changes to Subversion 
git svn dcommit 

# check for new branches 
git svn fetch

El flujo de trabajo de arriba es para un cambio continuo en una sola rama de Subversion a la que usted tiene el lujo de un poco cometer, sino múltiple malabares Las ramas activas de Subversion y git son un poco complicadas.

Para rastrear la rama Waldo del depósito de la subversión, empezar con

git checkout -b waldo-svn remotes/waldo

El sufijo -svn es evitar las advertencias de la forma

warning: refname 'waldo' is ambiguous.

y también para recordarle que esta rama git es para rastrear la rama Subversion. ¡Siempre mantenga los cambios en estas ramas lineales!

Para actualizar Waldo-svn, ejecute

git svn rebase

Esto obtendrá los cambios de Subversion y rebase los cambios locales en la parte superior de ellos. También es lo suficientemente inteligente como para reconocer cuando uno de sus cambios locales ha sido aceptado literalmente en sentido ascendente: será reemplazado por la confirmación de Subversion y tendrá una línea que comienza con git-svn-id: ... en su mensaje de confirmación.

Cuando los mantenedores de fuente alteran el contenido y la estructura de los parches (por ejemplo, modificando el código, la división de un parche en Subversion múltiples compromete, o la combinación de varios parches en una única confirmación) es cuando la vida es diversión resolución de conflictos y tratando de desenredar el desastre.

Para una generalidad general, mantenga sus ramas -svn en git limpias (sin cambios) y cree ramas de problemas en las ramas -svn. Para enviar un parche, utilice

git diff waldo-svn waldo-fix-frobnicator

Luego, cuando se git svn rebase a ponerse al día con el repositorio de Subversion, que necesita para revisar el registro y decidir sobre las respectivas disposiciones de sus ramas de emisión, una especie de GTD de Git .

+3

+1 para "mantener limpias sus ramas svn". Básicamente no son * sus * ramas svn, son ramas ascendentes, y por lo tanto, deben persistir también en su repositorio local de Git como ramas separadas. Si eso se cumple, puedes noq simplemente trabajar con ellos de la misma manera que con las ramas ascendentes de Git. –

+1

Thx para una respuesta tan larga gbacon. Pero esa no es la parte con la que estoy teniendo problemas. He reformulado la pregunta, espero que ahora sea más clara. –

+2

Un sinónimo más simple para '-T trunk -b branches -t tags' es' -s'. – l0b0

1

No estoy muy seguro de haber entendido su problema, pero creo que podría estar buscando git stash.

+0

Gracias esto ayudará un poco, pero no es una solución para todo el problema. –

1

No estoy seguro de cuán altamente acopladas están sus características con el código en sentido ascendente, pero es posible que pueda ramificar un "núcleo" del upstream que mantenga separado de sus funciones adicionales. Esto solo funciona si puedes dividir la base de código.

+0

Bueno, yo participo el código. Mantengo una parte del código completamente desarticulada de la base porque la cantidad de parches contra este código hace que las correcciones de errores aguas arriba sean irrelevantes. El problema es el resto del código. –

0

Realmente no has dejado claro lo que quieres hacer. En referencia a su afirmación de que "(mantener una rama separada para cada característica es, por lo tanto, no trivial)", solo puedo preguntar por qué cree que debería ser trivial. Dos parches que son mutuamente dependientes entre sí deben ser un solo parche, o al menos en una sola rama. Un parche B que depende de A (pero no de la otra) debe estar en la rama con A, o en una rama con una confirmación principal en la rama A.

Ahora, si desea mantener una "visión clara" de dónde están sus parches en sentido ascendente, eso se reducirá a mantener una copia local de todas las ramas ascendentes. No veo dónde está el problema con eso. Realmente necesita ser preciso si quiere una respuesta más precisa.


Ok, esto es más fácil de abordar ahora.

Tiene dos problemas.

(1) es obtener confirmaciones de horquillas que nunca irán hacia arriba fuera de la rama de desarrollo principal y hacia una bifurcación de horquilla una vez que se da cuenta de que nunca las está devolviendo.

Haga una bifurcación de la bifurcación. Una vez que se da cuenta de que una característica no retrocede, tire de la rama que sostiene la función de horquilla. Luego, git revert la función de horquilla para aplicar un parche que deshace la función de local- *. Repita según sea necesario.

(2) Es que te preocupa lo que le sucede al parche corriente arriba.

No debería tener que rastrear si ya han aplicado su parche a la versión remota (en adelante r-estable). No perderá un parche en L-stable si tira de r-stable y aún no lo han aplicado. El único problema posible es que habrá conflictos de combinación en el código del parche, pero no podrá evitarlo. Una vez que apliquen el parche, se verá exactamente como la forma en que resolvió los conflictos de fusión (en cuyo caso no obtendrás ninguna diferencia de eso cuando saques el parche de R-stable), o se fusionarán de una manera diferente , y obtendrá un conflicto de fusión y se le dará la oportunidad de decidir mantener su camino o su camino. Solo recuerde que si quiere mantener su camino, estará bifurcando desde el establo. Una opción es moverse "a tu manera" en el tenedor y seguir su camino en local- *.

+0

He reformulado la pregunta una vez más. Espero que ahora esté claro. –