2009-03-24 10 views
24

Parece que no puedo asimilar las diferentes soluciones que he encontrado y estudié para rastrear el código externo. Y mucho menos entiendo cómo aplicarlos a mi caso de uso ...Código de seguimiento de terceros con Git

¿Podrían ser tan amables de arrojar algo de luz sobre esto y ayudarme con mi caso de uso específico? ¿Cuál sería la mejor solución para el siguiente problema concreto, ? (No voy a intento de generalizar mi problema , ya que podría hacer suposiciones incorrectas sobre las cosas, sobre todo ya que soy tan nuevo con todo esto ...)

Estoy construyendo un sitio web en Django (un marco web en Python). Ahora, , hay muchos complementos de terceros disponibles para usar con Django (Django los llama 'aplicaciones'), que puede incluir en su proyecto. Algunas de estas aplicaciones pueden requerir un poco de modificación para funcionar como I . Pero si comienza a hacer modificaciones en el código de terceros, introduce el problema de actualizar ese código cuando aparecen versiones más nuevas Y al mismo tiempo, conserva sus modificaciones locales.

Por lo tanto, la forma en que lo haría en Subversion es mediante el uso de sucursales de proveedores. Mi entorno del repositorio se vería así:

/trunk 
    ... 
    /apps 
    /blog-app 
    ... 
/tags 
    ... 
/branches 
    ... 
/vendor 
    /django-apps 
    /blog-app 
     /1.2 
     /1.3 
     /current 
    /other-app 
     /3.2 
     /current 

En este caso/trunk/aplicaciones/blog aplicación habría sido SVN copy'd de uno de las etiquetas en/vendor/django-apps/blog- aplicación Digamos que era v1.2. Y que ahora quiero actualizar mi versión en trunk a v1.3. Como puede ver, ya he actualizado/vendor/django-apps/blog-app/current (usando svn_load_dirs) y 'tagged' (svn copy) como /vendor/django-apps/blog-app/1.3 . Ahora puedo actualizar/trunk/apps/blog-app mediante svn fusionando los cambios entre /vendor/django-apps/blog-app/1.2 y /vendor/django-apps/blog-app/1.3 en/trunk/apps/blog-app. Esto hará que guarde mis cambios locales. (por personas desconocidas con este proceso, que se describe en el manual Subversion: http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html)

Ahora quiero hacer todo este proceso en Git. ¿Cómo puedo hacer esto?

Permítanme reiterar los requisitos:

  • debo ser capaz de colocar el código externo en una posición arbitraria en el árbol
  • que debe ser capaz de modificar el código externo y mantener (commit) estas modificaciones en mis repositorios Git
  • debo ser capaz de actualizar fácilmente el código externo, debe ser liberado una nueva versión , manteniendo mis cambios

extra (para puntos de bonificación ;-)):

  • Preferiblemente quiero hacer esto sin algo así como svn_load_dirs. Creo que es posible rastrear las aplicaciones y sus actualizaciones directamente desde su repositorio (la mayoría de las aplicaciones de Django de terceros se guardan en Subversion).Me brindó la ventaja adicional de poder ver los mensajes de compromiso individuales entre lanzamientos. Y solucionar los conflictos de combinación más fácilmente ya que puedo manejar un montón de confirmaciones pequeñas en lugar de la única confirmación artificial creada por svn_load_dirs. creo que se podría hacer esto con svn: externos en Subversion, pero tengo nunca se trabajó con eso antes ...

Una solución donde una combinación de ambos métodos se podría utilizar sería aún más preferible, dado que podría haber desarrolladores de aplicaciones que no usan usan el control de fuente o no ponen sus repos disponibles públicamente. (Es decir, tanto el comportamiento svn_load_dirs similar desplazando derecho de un reposity Subversion (u otra Git))

creo que tendría o bien tienen que utilizar subárboles, cartuchos, rebase, ramas, ... o una combinación de los , pero bájame si sé cuál (es) o cómo hacerlo: S

¡Espero con ansias tus respuestas! Sea lo más detallado posible al responder, ya que tuve dificultades para comprender otros ejemplos de que se encuentran en línea.

Gracias de antemano

+0

¿Ya tiene su "aha" mientras tanto? También estoy buscando esto y todavía estoy un poco inseguro de cómo hacerlo. – acme

+0

Bueno, ciertamente he aprendido mucho más sobre Git desde que escribí esta pregunta y también tengo una mejor idea de agregar controles remotos y fusionarme en ramas/etiquetas de esos controles remotos. De hecho, estoy usando algo así como ahora también en el trabajo. Mantén nuestra Drupal instalada al día. – hopla

+0

En lo que concierne a los submódulos: realmente no los he probado aún, pero entiendo su esencia ahora. Sin embargo, parece un sistema muy complicado y propenso a errores. Entonces, ¿cómo hago mis instalaciones de Django ahora? Bueno, también tuve un momento de 'aha' en Django y aprendí muchos métodos legítimos que se pueden usar para extender aplicaciones. Y entonces simplemente instalé aplicaciones externas en virtualenv con pip, que es 'el camino correcto' de todos modos. Así que casi evité el problema y también obtuve una solución mucho mejor en su lugar :) – hopla

Respuesta

27

Hay dos problemas separados aquí:

  1. ¿Cómo se mantiene tenedores locales de proyectos remotos, y
  2. Cómo hacer que mantener una copia de proyectos remotos en su propio árbol?

El problema 1 es bastante fácil en sí mismo. Simplemente haga algo como:

git clone git://example.com/foo.git 
cd foo 
git remote add upstream git://example.com/foo.git 
git remote rm origin 
git remote add origin ssh://.../my-forked-foo.git 
git push origin 

A continuación, puede trabajar normalmente en su repositorio bifurcado. Cuando se desea combinar en cambios ascendentes, ejecute:

git pull upstream master 

En cuanto a problema 2, una opción es usar submódulos. Para ello, CD en su proyecto principal, y corro:

git submodule add ssh://.../my-forked-foo.git local/path/for/foo 

Si uso submódulos git, ¿qué necesito saber?

Puede que los submódulos de git sean un poco complicados a veces.Aquí hay algunas cosas a tener en cuenta:

  1. Siempre confirme el submódulo antes de asignar el elemento primario.
  2. Empuje siempre el submódulo antes de empujar el elemento primario.
  3. Asegúrate de que la CABEZA del submódulo apunta a una rama antes de comprometerte con ella. (Si es usuario de bash, le recomiendo que use git-completion para poner el nombre de la bifurcación actual en su mensaje.)
  4. Siempre ejecute la 'actualización del submódulo git' después de cambiar de rama o de hacer cambios.

Puede solucionar (4), en cierta medida mediante el uso de un alias creado por uno de mis compañeros de trabajo:

git config --global alias.pull-recursive '!git pull && git submodule update --init' 

... y luego ejecutar:

git pull-recursive 

Si los submódulos de Git son tan complicados, ¿cuáles son las ventajas?

  1. Puede consultar el proyecto principal sin consultar los submódulos. Esto es útil cuando los submódulos son enormes y no los necesita en ciertas plataformas.
  2. Si ha experimentado usuarios de git, es posible tener varias bifurcaciones de su submódulo y vincularlas con diferentes bifurcaciones de su proyecto principal.
  3. Algún día, alguien podría arreglar los submódulos de git para trabajar con más elegancia. Las partes más profundas de la implementación del submódulo son bastante buenas; son solo las herramientas de nivel superior las que están rotas.

git submódulos no son para mí. ¿Qué sigue?

Si no desea utilizar los submódulos de git, es posible que desee consultar git merge's subtree strategy. Esto mantiene todo en un repositorio.

¿Qué ocurre si el repositorio en sentido ascendente utiliza Subversion?

Esto es bastante fácil si sabes cómo utilizar git svn:

git svn clone -s https://example.com/foo 
cd foo 
git remote add origin ssh://.../my-forked-foo.git 
git push origin 

A continuación, establecer una sucursal de seguimiento local en Git.

git push origin master:local-fork 
git checkout -b local-fork origin/local-fork 

Entonces, para fusionar desde aguas arriba, ejecute:

git svn fetch 
git merge trunk 

(no he probado este código, pero es más o menos cómo mantenemos un submódulo con un repositorio SVN aguas arriba.)

No use git svn rebase, porque hará que sea muy difícil usar el submódulo de git en el proyecto principal sin perder datos. Simplemente trate las ramificaciones de Subversion como réplicas de solo lectura de upstream, y fusionelas explícitamente.

Si necesita acceder al repositorio de Subversion aguas arriba en otra máquina, pruebe:

git svn init -s https://example.com/foo 
git svn fetch 

A continuación, debería ser capaz de combinar los cambios de aguas arriba como antes.

+0

El truco aquí es usar submódulos con git-svn. –

+0

Ryan: Agregué algunos ejemplos de Subversion no probados, basados ​​en un submódulo que configuré hace unos días. Si se rompe, házmelo saber y lo arreglaré. – emk

+0

emk: esta es una muy buena descripción, gracias! Todavía no tengo mi 'aha!' momento, pero creo que tendré que probar cosas. Dado que no voy a presionar mis cambios, creo que el método de fusión del subárbol sería mi mejor opción. ¿Puedo usar eso en combinación con git-svn? – hopla

1

que utilizan submódulos git para rastrear aplicaciones reutilizables en mis proyectos de Django, pero es una especie de desordenado en el largo plazo.

Desorganizar la implementación porque no se puede obtener un archivo limpio de todo el árbol (con submódulos) usando git archive. Hay algunos trucos, pero nada perfecto. Además, el mecanismo de actualización de submódulos no es tan bueno para trabajar con ramas de submódulos.

Es posible que tenga que echar un vistazo a virtualenv y pip, porque tuvieron algunas mejoras recientes para trabajar con repositorios externos.

pip: http://pip.openplans.org/ y trabajar con PIP/virtualenv: http://www.b-list.org/weblog/2008/dec/15/pip/

+0

¿Qué tan complicado se vuelve? ¿De dónde viene el desastre? ¿Me puede dar una URL a este "cerdo" cosa? Buscar en Google 'git pig' o 'python pig' da resultados mixtos (sobre serpientes comiendo cerdos, etc.). – hopla

+0

lo siento, hice un error tipográfico en el cerdo: es pip. –

+0

Ok, gracias. ¿Sería capaz de hacer cambios locales usando virtualenv o pip? (y conserve esos cambios cuando actualice el código de terceros) – hopla

3

Miré un poco más y tropecé con Braid. Es una herramienta que automatiza las sucursales de proveedores en Git. Puede usar repositorios Git o SVN.

Al rastrear la fuente descubrí que utiliza la estrategia de subárbol. ¡Y parece hacerlo realmente simple! ¡Además, parece cumplir todos mis requisitos!

Antes de saltar y usarlo: ¿alguien aquí tiene alguna experiencia con Braid? Me gustaría averiguar sobre posibles inconvenientes si los hay. Además, si no ha usado Braid, pero tiene cierta experiencia en Git, ¿qué piensa al respecto, a primera vista?

0

Creo que mi respuesta a otras preguntas ofrece exactamente una buena solución para el problema descrito aquí, sin entrar en el infierno de los submódulos (que he intentado, pero ni siquiera me acerco a la svn: Externals I was utilizado para)

aún así, echar un vistazo a esta respuesta: Do you version control the invidual apps or the whole project or both?

Antes de eliminar mi respuesta de nuevo, yo no era consciente de que no podía copiar mi propia respuesta a otra pregunta, aunque estoy convencido de que es útil como una respuesta. Lo siento, pero pruebe esta respuesta, realmente es una buena solución. Así que espero poder consultar mi propia respuesta a otra pregunta.

Cuestiones relacionadas