git - tag - Cómo mantener(en su mayoría) ramas paralelas con solo unas pocas diferencias
git remove tag (3)
Escenario: Estoy tratando de obtener mis archivos de puntos de Unix bajo git. Tengo que trabajar entre (al menos) el entorno cygwin y algunas distribuciones de linux estándar (ubuntu y opensuse), y tengo archivos / líneas de código que son solo específicos para, por ejemplo, cygwin. Ya que no quiero sacar archivos inútiles o tener que lidiar con muchos casos dentro de mis archivos de puntos, estoy creando sucursales para cada uno de mis entornos. Pero la mayoría de las ediciones que hago son comunes a todos los entornos, por lo que casi cada vez que hago un compromiso necesito propagar ese cambio a todas mis sucursales.
Básicamente, tengo varias sucursales que son casi idénticas, excepto por algunas confirmaciones, y la mayoría de las confirmaciones que necesito están en todas las sucursales.
La pregunta: ¿cuál es el flujo de trabajo de Git recomendado para esto, si hay alguno? ¿O hay una mejor configuración (sin usar múltiples sucursales) para mi escenario?
[Intenté hacer una selección de cerebros, pero eso implica un poco de trabajo, y sin mencionar todos los compromisos duplicados aquí y la pesadilla es mantener mis sucursales sincronizadas.]
Buena pregunta. Aunque dijiste:
... ya que no quiero sacar archivos inútiles ...
Me gustaría colocar los elementos específicos de la plataforma o de la variante en la misma rama que el código principal, pero en un directorio separado para esa plataforma / variante. La clave es aislar las cosas específicas de la plataforma en un área lo más pequeña posible (es decir, evitar las ifdef
en el código principal).
P.ej:
/
+--common
+--linux
+--cygwin
+--windows
+--mac
Varios proyectos multiplataforma se organizan de esta manera. Por ejemplo, consulte la estructura del código fuente de Python para admitir múltiples plataformas.
Simplifica su flujo de trabajo en este sentido, por lo que es más libre de usar sucursales para otros fines más interesantes.
Para ese caso en particular, donde hay una gran cantidad de archivos comunes que evolucionan en una rama, y solo unos pocos archivos de configuración específicos para cada entorno ... no almacenamos el archivo de configuración en Git. En absoluto.
Almacenamos la plantilla de dichos archivos de configuración, más todos los valores específicos por entorno, más un script capaz de reemplazar las variables en los archivos de plantilla por el valor correcto (detección de la plataforma actual)
De esa manera, no necesitamos hacer una rama solo para esos archivos.
Otra buena forma de administrar ese tipo de archivos (con un contenido específico de la plataforma) es a través de un controlador de filtro de atributo git (ver también el libro Pro Git ).
Un controlador de filtro consta de un comando de
clean
y un comando desmudge
, cualquiera de los cuales se puede dejar sin especificar.
En el momento de lasmudge
, cuando se especifica el comando smudge, el comando se alimenta con el objeto blob desde su entrada estándar, y su salida estándar se usa para actualizar el archivo de worktree.
De manera similar, el comando declean
se usa para convertir el contenido del archivo de worktree al momento del registro.
De esa manera, un script (administrado con Git) al que hace referencia la mancha puede reemplazar todas las variables por valores específicos de la plataforma, mientras que el script limpio restaurará su contenido en un archivo de configuración intacto.
La idea principal sigue siendo: evitar crear ramas solo para ese tipo de evolución paralela.
Un enfoque es mantener una rama para cada entorno, más una rama "maestra" que sea común a todos los entornos. Cada vez que realice un cambio en la rama maestra y desee insertarlo en otro sistema, haga algo como:
git pull
git checkout local
git rebase master
Esto reescribirá los cambios actuales en "local" (que son para este entorno particular) contra el estado actual de "maestro".
La cosa manual a la que deberías prestar atención es en donde comprometes un cambio que deseas realizar. Si es local para un sistema, confírmelo en la rama "local" de ese sistema, de lo contrario, confírmelo en "maestro" y colóquelo en un repositorio común.
Por supuesto, la reorganización puede dar lugar a conflictos que debe resolver manualmente. Además, si elige insertar sucursales locales en el repositorio común, tendrá que (a) elegir nombres únicos para cada entorno, y (b) lidiar con los impulsos de no avance rápido después de la rebasación. Ambos problemas son solucionables.