trabajando con git en un proyecto web para múltiples clientes

¿Existe una mejor propuesta para el control de versiones de proyectos web con pequeñas actualizaciones aleatorias en varios proyectos de clientes con git?

Quiero usar git para el control de versiones para proyectos web. La principal diferencia para casi todas las demás propuestas es que se trata de un proyecto web que utiliza HTML, JavaScript y algunos files PHP; no hay bibliotecas centrales utilizadas por uno o más progtwigs, como es habitual en los packages típicos de Linux.

Todos mis proyectos web diferentes son para diferentes clientes basándose en los mismos files de plataforma; estimaría que el 80% de los files son idénticos (llámelos plataforma) y el 20% se modifican para que diferentes clientes se ajusten a sus necesidades. El problema aquí es que no sé para qué files necesitamos una actualización del cliente: en detalle, cada cliente es diferente.

Lo mejor sería mantener los files específicos de la plataforma en un directory y superponer estos files con files específicos del cliente en otro directory. Para resolver esto con git no encontré nada realmente bueno hasta ahora:

  • El submodule git (como el que se propone aquí ) normalmente está diseñado para tener las fonts de una biblioteca desarrollada por un proveedor cercana al progtwig que lo vincula. Por lo tanto, el problema es que la plataforma y los files del cliente están en directorys diferentes, por lo que debo mezclarlos durante la implementación para crear los files para el server web. Además, tengo que mantener los treees de directorys sincronizados de forma manual, y eso sería mucho trabajo con 10 jerarquías profundas de directorys. En general, muchas publicaciones se quejan del gran esfuerzo administrativo que utiliza los submodules, parece que es excesivo.
  • El subtree de git (como el que se propone aquí ) parece ser más simple que el submodule, pero tiene el mismo problema con diferentes directorys, por lo que también necesito mantener la estructura de directorys sincronizada y mezclar los files durante la implementación. Además, es difícil hacer retroceder los cambios de plataforma desde el repository de clientes.
  • GitSlave (como se propone aquí ) No estoy seguro de si esto puede ser beneficioso para mí. Permite mantener varios repositorys git sincronizados, quizás ayude a sincronizar la estructura dir de la plataforma, pero no lo puedo creer
  • Refactor entre la plataforma y los files del cliente en diferentes directorys (como el resultado de esta discusión). Creo que esto es simplemente imposible en el caso de mis clientes y la tecnología utilizada por los proyectos web. Para un cliente esta página necesita una actualización, para otra esa página. Incluso cuando se introduce un marco PHP, los cambios específicos del cliente se extienden por todo el tree.
  • Pagos (como también se propuso en esta discusión en la última publicación) Esto parece muy simple y prometedor, con el inconveniente de que todos los files específicos del cliente están fuera de git (por lo tanto, fuera del control de la versión). Además, en caso de que un file se actualice en la plataforma y en el cliente, la extracción de git falla; aborta, por lo que no es utilizable.
  • Vendor Branches (como se reinició aquí ), como he aprendido, las sucursales están hechas para fusionarse, y eso no está dirigido a mis parches específicos del cliente. Estas sucursales estarían siempre abiertas, solo fusionadas después de una actualización desde la plataforma (principal) hacia el cliente. Y esto dará lugar a un repository mega litio que mantendrá a todos los clientes y la información de la plataforma, y ​​no la manera incorrecta de manejar los repos.
  • Mezcle durante la implementación . Es un método muy pragmático para mantener los files de la plataforma en un repository y los files del cliente también en repositorys dedicados. Durante la implementación de los files en el server web, primero puede escribir todos los files de la plataforma y sobrescribir algunos de ellos mediante los files específicos de la plataforma. La mezcla ocurre muy tarde en el directory de serveres web. Esto también tiene el inconveniente de que la estructura de directorys de cada cliente debe mantenerse manualmente sincronizada con la estructura de la plataforma; de lo contrario, la implementación sería demasiado compleja.

¿Cuál es el mejor enfoque aquí?

TL; DR

Esto es realmente un problema de layout arquitectónico, no un problema de gestión del código fuente. Sin embargo, es un problema común e interesante , por lo que estoy ofreciendo algunos consejos generales sobre cómo abordar sus problemas arquitectónicos.

No es realmente un problema Git

El problema no es realmente Git aquí. El problema es que no ha diferenciado adecuadamente lo que permanece igual frente a lo que cambiará entre los clientes. Una vez que haya determinado el patrón de layout correcto, el model de control de fuente apropiado será más obvio.

Considere esta cita de Russ Olsen:

[Separar] las cosas que probablemente cambiarán de las cosas que probablemente se mantendrán iguales. Si puede identificar qué aspectos del layout de su sistema es probable que cambien, puede aislar esos bits de las partes más estables.

Olsen, Russ (2007-12-10). Patrones de layout en Ruby (Ubicaciones Kindle 586-588). Pearson Education (Estados Unidos). Versión Kindle.

Algunas sugerencias de refactorización

No conozco su aplicación lo suficientemente bien como para ofrecer consejos concretos, pero en general los proyectos web pueden beneficiarse de un par de patrones de layout diferentes. Los patrones de templates, compuestos o prototypes pueden ser todos aplicables, pero a veces los patrones de discusión confunden el problema más de lo que ayuda.

Sin un order en particular, esto es lo que yo personalmente haría:

  1. En la capa de vista, confíe mucho en las templates. Haga un uso intensivo de layouts, inclusiones o parciales, para que pueda componer más fácilmente los objects de la capa de presentación.
  2. Haga un uso intensivo de los files de configuration específicos del cliente (prefiero YAML para este propósito) para permitir una personalización más sencilla sin modificar el código del núcleo.
  3. En las capas de model y controller, elija algunos patrones estructurales apropiados para permitir que sus objects se comporten polimórficamente en function de los files de configuration específicos del cliente. Duck-typing es tu amigo aquí!
  4. Utilice una introspección basada en el nombre de host o dominio, lo que permite un comportamiento polimórfico para cada cliente.

Siguientes pasos con Git

Una vez que haya networkingiseñado su aplicación para minimizar los cambios entre los clientes, es posible que ni siquiera necesite mantener su código separado a less que intente ocultar el código polimórfico de cada cliente. Si tal es el caso, ciertamente puede investigar submodules o twigs separadas en ese punto, pero sin la carga de una gran duplicación entre twigs.

Los enlaces simbólicos son tus amigos, también

Por último, si encuentra que puede aislar los cambios en unos pocos subdirectorys, Git admite enlaces simbólicos. Simplemente podría tener todo su código variado en un subdirectory por cliente en su sucursal de desarrollo, y vincular simbólicamente los files en los lugares correctos en sus twigs de publicación por cliente. Incluso puede automatizar esto con algunos scripts de shell o durante implementaciones automatizadas.

Esto mantiene todo su código de desarrollo en un solo lugar para facilitar las comparaciones y la refactorización (por ejemplo, la twig de desarrollo), pero asegura que el código que realmente necesita ser diferente para cada lanzamiento es donde debe estar cuando lo ponga en producción.

Las sucursales de proveedores tienen más sentido debido a la naturaleza de cómo personaliza su solución para cada proveedor. La mejor manera de hacerlo es olvidarse de esto y desarrollar una aplicación multi-tenant .