Alex Napitupulu
Tengo un proyecto que tiene partes de cliente y servidor. Me gustaría que el código del cliente y del servidor estuvieran en diferentes repositorios de Git para una separación clara del código, sin embargo, comparten algunos archivos e, idealmente, los archivos compartidos siempre serán idénticos tanto en el cliente como en el servidor.
¿Cómo debo hacer esto? ¿Es mejor tener el tercer repositorio para el código común?
No daré consejos sobre “Cómo debe hacer esto”. Pero explicaré cómo lograr integrar un tercer repositorio con código común en los otros repositorios: Este es un trabajo para los submódulos de git. Los submódulos de git le permiten hacer referencia a una instantánea de un repositorio de git en una ruta específica:
git submodule add git://example.com/repository.git path
Luego crea un compromiso. Ahora se hace referencia a una instantánea del repositorio dado en path
.
Llenar el submódulo
- Ejecutar
git submodule init
- Ejecutar
git submodule update
Cada submódulo configurado se actualizará para que coincida con el estado en el que se supone que debe verse.
Actualización de un submódulo a una confirmación posterior
- Cambiar al directorio del submódulo
- realizar un
git pull
/git fetch
+git checkout
para actualizar el submódulo a la confirmación / etiqueta deseada - Cree una nueva confirmación para actualizar la confirmación en el
.gitmodules
archivo
Echa un vistazo a la manual oficial para obtener más información sobre los submódulos.
-
Vale la pena mencionar que los submódulos solo rastrearán desde la rama principal.
– DevYego
11 de abril de 2020 a las 7:40
-
@DevYego No estoy seguro de lo que quieres decir con eso. Puede hacer que los submódulos apunten a cualquier confirmación, no solo a la rama principal. El seguimiento es un concepto de sucursales locales frente a remotas, y esto se puede administrar dentro del git de cada submódulo; no es consciente de que es un submódulo.
–Amichai Schreiber
15 de julio de 2020 a las 11:37
Schwern
Si comparten código común, veo dos opciones sensatas. Separe el código común en su propio proyecto, o combine los repositorios del servidor y del cliente para facilitar el trabajo en conjunto.
Depende de usted si separar el código común vale la pena el esfuerzo adicional. ¿El código común tiene sentido por sí solo o es solo un conjunto de funciones específicas de este producto? Por ejemplo, si tuviera un SSL o un código de análisis de fecha en común, sería un buen proyecto derivado. O tal vez haya escrito un código especial para el análisis de archivos de configuración, que se puede trabajar de forma independiente incluso si nadie más que su proyecto lo usará. Si está creando un código común solo porque los dos proyectos lo comparten, no se moleste, no tendrá una dirección propia. Escindirlo solo será una barrera para el desarrollo tanto para el servidor como para los equipos del cliente.
Si debe fusionar el cliente y el servidor es otra consideración. También se reduce a si tiene sentido considerarlos como productos separados. ¿Son útiles como productos separados? ¿Pueden funcionar juntas versiones diferentes del cliente y el servidor, o deben ser la misma versión? ¿Trabajan diferentes personas en el cliente y en el servidor? El hecho de que quieras mantener todo junto en un superrepositorio dice que no.
Si se separa en varios repositorios (cliente, servidor, proyectos relacionados), siga la respuesta de TimWolla.
Si no está seguro, combínelos todos en un repositorio con server/
, client/
y common/
directorios de primer nivel. Si sus preocupaciones están enredadas, júntalas. Esto también facilitará la detección y migración de código duplicado. Puede trabajar para desenredarlos y crear proyectos “comunes” concretos, y en ese momento deben separarse en sus propios repositorios.
TL;DR
Simplemente use los submódulos de Git para mantener su código común. Ese es el caso de uso para el que están destinados. Existen otras opciones, pero principalmente para repositorios en el mismo sistema de archivos y con pocas ventajas cuando se clonan en una red.
Código común frente a archivos idénticos
La forma correcta de lidiar con el código común suele ser a través de submódulos o fusión de subárboles. Sin embargo, si tiene activos de archivo que son (y seguirán siendo) idénticos, puede aprovechar los enlaces simbólicos en los sistemas de archivos que los admitan. Hay al menos tres desventajas en este enfoque:
- Solo un repositorio tendría el archivo “real”. El otro repositorio solo contendría un enlace simbólico a un archivo que puede o no existir en un sistema de archivos diferente.
- Los sistemas Windows no tienen enlaces simbólicos de estilo Linux/Unix, por lo que la interoperabilidad puede ser un problema.
- A menos que se trate de blobs binarios realmente grandes, el ahorro de espacio de los enlaces compartidos probablemente sea mínimo y no valga la pena el esfuerzo.
También puede investigar el uso de suplentes para compartir objetos entre repositorios en el mismo sistema de archivos. El manual dice (énfasis mío):
Podrías estar usando los mecanismos objects/info/alternates o $GIT_ALTERNATE_OBJECT_DIRECTORIES para tomar prestados objetos de otras tiendas de objetos. Un repositorio con este tipo de almacén de objetos incompletos no es adecuado para ser publicado para su uso con transportes tontos, pero por lo demás está bien siempre que los objetos/información/alternativos apunten a los almacenes de objetos de los que toma prestado.
Este tipo de uso avanzado generalmente se usa para acelerar la bifurcación en sistemas como Atlassian Stash en lugar de compartir blobs específicos, pero las herramientas están ahí si desea hacer malabarismos con motosierras.
-
Se siente extraño que un repositorio tenga el archivo “real” en el caso de que no sea obvio elegir uno sobre el otro. Debería recordar qué repositorio tiene el archivo real
– Guillermo Mosse
28 de enero de 2022 a las 11:32
Use submódulos, subárboles o subrepos:
https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407
https://medium.com/@porteneuve/mastering-git-subtrees-943d29a798ec
use un administrador de paquetes (como NPM para node.js, depende de su idioma/entorno),
mover los archivos comunes a un paquete,
tal vez agregue un script posterior a la instalación,
e instale el paquete común tanto en el paquete del cliente como en el del servidor