tag - Seguimiento de código de terceros con Git
git tags best practices (4)
Creo que mi respuesta a otras preguntas ofrece exactamente una buena solución para el problema que se describe aquí, sin pasar por los infiernos de los submódulos (que he intentado, pero que ni siquiera se acercan a los svn: externos a los que estaba acostumbrado)
De todos modos, eche un vistazo a esta respuesta: ¿Controla la versión de las aplicaciones individuales o el proyecto completo o ambos?
Antes de volver a eliminar mi respuesta, no sabía que no podía copiar mi propia respuesta a otra pregunta, incluso si estoy convencido de que es útil como respuesta. Lo siento, pero pruebe esta respuesta, realmente es una buena solución. Así que espero que se me permita referir mi propia respuesta a otra pregunta.
Parece que no puedo asimilar las diferentes soluciones que he encontrado y estudiado para rastrear código externo. Y mucho menos entender cómo aplicarlos a mi caso de uso ...
¿Serían 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 intentar generalizar mi problema, ya que podría hacer suposiciones erróneas sobre las cosas, especialmente porque soy tan nuevo con todo esto ...)
Estoy construyendo un sitio web en Django (un marco web en Python). Ahora, hay una gran cantidad de complementos de terceros disponibles para usar con Django (Django los llama ''aplicaciones''), que puede colocar en su proyecto. Algunas de estas aplicaciones pueden requerir un poco de modificación para que funcionen como yo las quiero. Pero si comienza a realizar modificaciones en el código de terceros, se presenta el problema de actualizar ese código cuando aparecen versiones más nuevas Y al mismo tiempo mantener sus modificaciones locales.
Entonces, la forma en que lo haría en Subversion es mediante el uso de sucursales de proveedores. El diseño de mi 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 / apps / blog-app se habría copiado de una de las etiquetas en / vendor / django-apps / blog-app. Digamos que era v1.2. Y que ahora quiero actualizar mi versión en tronco 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 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 mantendrá mis cambios locales. (para personas desconocidas con este proceso, se describe en el manual de 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 repetir los requisitos:
- Debo poder colocar el código externo en una posición arbitraria en el árbol
- Debo poder modificar el código externo y guardar (confirmar) estas modificaciones en mis repositorios Git
- Debo poder actualizar fácilmente el código externo, en caso de que se lance una nueva versión, mientras mantengo mis cambios
Extra (para puntos de bonificación ;-)):
- Preferiblemente quiero hacer esto sin algo como svn_load_dirs. Creo que debería ser 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). Dándome el beneficio adicional de poder ver mensajes de confirmación individuales entre versiones. Y solucionar los conflictos de combinación más fácilmente, ya que puedo lidiar con muchos compromisos pequeños en lugar del compromiso artificial creado por svn_load_dirs. Creo que uno haría esto con svn: externals en Subversion, pero nunca he trabajado con eso antes ...
Una solución en la que se pudiera usar una combinación de ambos métodos sería aún más preferible, ya que podría haber desarrolladores de aplicaciones que no usan el control de código fuente o no hacen públicos sus repositorios. (Es decir, tanto el comportamiento de svn_load_dirs-like como el seguimiento directo desde una posición de Subversion (u otro Git))
Creo que tendría que usar subárboles, submódulos, rebase, sucursales, ... o una combinación de ellos, pero darme una paliza si sé cuál (es) o cómo hacerlo: S
¡Estoy esperando con impaciencia sus respuestas! Sea lo más detallado posible cuando responda, ya que me costó mucho entender otros ejemplos encontrados en línea.
Gracias por adelantado
Hay dos problemas separados aquí:
- ¿Cómo mantener las horquillas locales de proyectos remotos, y
- ¿Cómo conservas una copia de proyectos remotos en tu propio árbol?
El problema 1 es bastante fácil por sí mismo. Solo haz 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
Entonces puedes trabajar en tu repositorio bifurcado normalmente. Cuando desee fusionar los cambios en sentido ascendente, ejecute:
git pull upstream master
En cuanto al problema 2, una opción es usar submódulos. Para esto, cd en su proyecto principal, y ejecute:
git submodule add ssh://.../my-forked-foo.git local/path/for/foo
Si uso submódulos de git, ¿qué necesito saber?
Puede que los submódulos de git sean un poco difíciles a veces. Aquí hay algunas cosas a tener en cuenta:
- Siempre cometa el submódulo antes de cometer el padre.
- Siempre presione el submódulo antes de empujar al padre.
- Asegúrese de que la CABEZA del submódulo apunte a una rama antes de comprometerse con ella. (Si eres un usuario de bash, recomiendo usar git-completion para poner el nombre de la sucursal actual en tu solicitud).
- Ejecute siempre ''git submodule update'' después de cambiar de rama o de cambiar cambios.
Puede trabajar alrededor de (4) hasta cierto punto utilizando 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 corriendo:
git pull-recursive
Si los submódulos de git son tan complicados, ¿cuáles son las ventajas?
- Puedes revisar el proyecto principal sin revisar los submódulos. Esto es útil cuando los submódulos son enormes y no los necesita en ciertas plataformas.
- Si ha experimentado usuarios de git, es posible tener varias bifurcaciones de su submódulo y vincularlas con diferentes bifurcaciones de su proyecto principal.
- Algún día, alguien podría arreglar los submódulos de git para que funcionen con más gracia. Las partes más profundas de la implementación del submódulo son en realidad bastante buenas; son solo las herramientas de nivel superior las que están rotas.
Los submódulos de git no son para mí. ¿Qué sigue?
Si no desea utilizar los submódulos de git, es posible que desee examinar la estrategia de subárbol de git merge . Esto mantiene todo en un repositorio.
¿Qué pasa si el repositorio upstream utiliza Subversion?
Esto es bastante fácil si sabes cómo usar 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, configure una rama de seguimiento local en git.
git push origin master:local-fork
git checkout -b local-fork origin/local-fork
Luego, para fusionar desde el principio, 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 ascendente).
No use git svn rebase, ya que será muy difícil usar git submodule en el proyecto principal sin perder datos. Simplemente trate las ramas de Subversion como espejos de solo lectura en sentido ascendente, y fusione de ellas explícitamente.
Si necesita acceder al repositorio Subversion ascendente en otra máquina, intente:
git svn init -s https://example.com/foo
git svn fetch
Entonces deberías poder fusionar los cambios desde el nivel anterior como antes.
He mirado alrededor 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 que lo hace realmente simple! Además, parece cumplir con todos mis requisitos!
Antes de saltar y usarlo: ¿Alguien aquí tiene alguna experiencia con Braid? Me gustaría averiguar sobre posibles contras si hay alguna. Además, si no has usado Braid, pero tienes algo de experiencia en Git, ¿qué piensas al respecto a primera vista?
Utilizo los submódulos de git para rastrear aplicaciones reutilizables en mis proyectos de Django, pero a la larga es un poco desordenado.
Es complicado para la implementación porque no puede obtener un archivo limpio de todo el árbol (con submódulos) utilizando 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/